diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index dc0eb465b77d..e4d1f6376303 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -14,7 +14,9 @@ disabled: - x-pack/test/api_integration/config.ts - x-pack/test/fleet_api_integration/config.base.ts - x-pack/test/security_solution_api_integration/config/ess/config.base.ts + - x-pack/test/security_solution_api_integration/config/ess/config.base.basic.ts - x-pack/test/security_solution_api_integration/config/serverless/config.base.ts + - x-pack/test/security_solution_api_integration/config/serverless/config.base.essentials.ts - x-pack/test/security_solution_endpoint/config.base.ts - x-pack/test/security_solution_endpoint_api_int/config.base.ts @@ -318,6 +320,7 @@ enabled: - x-pack/test/functional/apps/transform/feature_controls/config.ts - x-pack/test/functional/apps/upgrade_assistant/config.ts - x-pack/test/functional/apps/uptime/config.ts + - x-pack/test/functional/apps/user_profiles/config.ts - x-pack/test/functional/apps/visualize/config.ts - x-pack/test/functional/apps/watcher/config.ts - x-pack/test/functional/config_security_basic.ts @@ -485,3 +488,6 @@ enabled: - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles/configs/ess.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/serverless.config.ts - x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry/configs/ess.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/serverless.config.ts + - x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/ess.config.ts + diff --git a/.buildkite/pipeline-utils/ci-stats/client.ts b/.buildkite/pipeline-utils/ci-stats/client.ts index 6a5c048464c7..d7367b89947a 100644 --- a/.buildkite/pipeline-utils/ci-stats/client.ts +++ b/.buildkite/pipeline-utils/ci-stats/client.ts @@ -201,7 +201,7 @@ export class CiStatsClient { headers: this.defaultHeaders, }); } catch (error) { - console.error('CI Stats request error:', error); + console.error('CI Stats request error:', error?.response?.data?.message); if (attempt < maxAttempts) { const sec = attempt * 3; @@ -210,7 +210,7 @@ export class CiStatsClient { continue; } - throw error; + throw new Error('Failed to connect to CI Stats.'); } } } diff --git a/.buildkite/pipelines/security_solution/api_integration.yml b/.buildkite/pipelines/security_solution/api_integration.yml index b4c6cece31c4..0fbc23bcab68 100644 --- a/.buildkite/pipelines/security_solution/api_integration.yml +++ b/.buildkite/pipelines/security_solution/api_integration.yml @@ -1,7 +1,7 @@ steps: - - label: Running exception_workflows:runner:serverless + - label: Running exception_workflows:qa:serverless command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_workflows:qa:serverless - key: exception_workflows:runner:serverless + key: exception_workflows:qa:serverless agents: queue: n2-4-spot timeout_in_minutes: 120 @@ -10,9 +10,9 @@ steps: - exit_status: '*' limit: 2 - - label: Running exception_operators_date_numeric_types:runner:serverless + - label: Running exception_operators_date_numeric_types:qa:serverless command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_date_numeric_types:qa:serverless - key: exception_operators_date_numeric_types:runner:serverless + key: exception_operators_date_numeric_types:qa:serverless agents: queue: n2-4-spot timeout_in_minutes: 120 @@ -21,9 +21,20 @@ steps: - exit_status: '*' limit: 2 - - label: Running exception_operators_keyword_text_long:runner:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_keyword_text_long:qa:serverless - key: exception_operators_keyword_text_long:runner:serverless + - label: Running exception_operators_keyword:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_keyword:qa:serverless + key: exception_operators_keyword:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '*' + limit: 2 + + - label: Running exception_operators_ips:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_ips:qa:serverless + key: exception_operators_ips:qa:serverless agents: queue: n2-4-spot timeout_in_minutes: 120 @@ -32,9 +43,9 @@ steps: - exit_status: '*' limit: 2 - - label: Running exception_operators_ips_text_array:runner:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_ips_text_array:qa:serverless - key: exception_operators_ips_text_array:runner:serverless + - label: Running exception_operators_long:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_long:qa:serverless + key: exception_operators_long:qa:serverless agents: queue: n2-4-spot timeout_in_minutes: 120 @@ -42,10 +53,22 @@ steps: automatic: - exit_status: '1' limit: 2 + - - label: Running rule_creation:runner:serverless + - label: Running exception_operators_text:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_text:qa:serverless + key: exception_operators_text:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running rule_creation:qa:serverless command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_creation:qa:serverless - key: rule_creation:runner:serverless + key: rule_creation:qa:serverless agents: queue: n2-4-spot timeout_in_minutes: 120 @@ -64,4 +87,92 @@ steps: automatic: - exit_status: '1' limit: 2 - + + - label: Running entity_analytics:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh entity_analytics:qa:serverless + key: entity_analytics:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running prebuilt_rules_management:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_management:qa:serverless + key: prebuilt_rules_management:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running prebuilt_rules_large_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_large_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_large_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running prebuilt_rules_update_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_update_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_update_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running rule_execution_logic:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_execution_logic:qa:serverless + key: rule_execution_logic:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running user_roles:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh user_roles:qa:serverless + key: user_roles:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + + - label: Running telemetry:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh telemetry:qa:serverless + key: telemetry:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 + \ No newline at end of file diff --git a/.buildkite/scripts/lifecycle/pre_build.sh b/.buildkite/scripts/lifecycle/pre_build.sh index 62f94dd493fa..b8ccaf04f9bb 100755 --- a/.buildkite/scripts/lifecycle/pre_build.sh +++ b/.buildkite/scripts/lifecycle/pre_build.sh @@ -8,8 +8,6 @@ if [[ "${GITHUB_BUILD_COMMIT_STATUS_ENABLED:-}" != "true" ]]; then "$(dirname "${0}")/commit_status_start.sh" fi -export CI_STATS_TOKEN="$(retry 5 5 vault read -field=api_token secret/kibana-issues/dev/kibana_ci_stats)" -export CI_STATS_HOST="$(retry 5 5 vault read -field=api_host secret/kibana-issues/dev/kibana_ci_stats)" ts-node "$(dirname "${0}")/ci_stats_start.ts" diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index 9cfa973b2802..965c09621caa 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -77,16 +77,16 @@ EOF { CI_STATS_BUILD_ID="$(buildkite-agent meta-data get ci_stats_build_id --default '')" export CI_STATS_BUILD_ID + + CI_STATS_TOKEN="$(retry 5 5 vault read -field=api_token secret/kibana-issues/dev/kibana_ci_stats)" + export CI_STATS_TOKEN + + CI_STATS_HOST="$(retry 5 5 vault read -field=api_host secret/kibana-issues/dev/kibana_ci_stats)" + export CI_STATS_HOST if [[ "$CI_STATS_BUILD_ID" ]]; then echo "CI Stats Build ID: $CI_STATS_BUILD_ID" - CI_STATS_TOKEN="$(retry 5 5 vault read -field=api_token secret/kibana-issues/dev/kibana_ci_stats)" - export CI_STATS_TOKEN - - CI_STATS_HOST="$(retry 5 5 vault read -field=api_host secret/kibana-issues/dev/kibana_ci_stats)" - export CI_STATS_HOST - KIBANA_CI_STATS_CONFIG=$(jq -n \ --arg buildId "$CI_STATS_BUILD_ID" \ --arg apiUrl "https://$CI_STATS_HOST" \ diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.ts b/.buildkite/scripts/steps/storybooks/build_and_upload.ts index 83f1ecb2a759..19fed0e78885 100644 --- a/.buildkite/scripts/steps/storybooks/build_and_upload.ts +++ b/.buildkite/scripts/steps/storybooks/build_and_upload.ts @@ -16,7 +16,6 @@ const STORYBOOKS = [ 'canvas', 'cases', 'cell_actions', - 'ci_composite', 'cloud_chat', 'coloring', 'chart_icons', @@ -93,14 +92,12 @@ const upload = () => { console.log('--- Generating Storybooks HTML'); process.chdir(path.join('.', 'built_assets', 'storybook')); - fs.renameSync('ci_composite', 'composite'); const storybooks = execSync(`ls -1d */`) .toString() .trim() .split('\n') - .map((filePath) => filePath.replace('/', '')) - .filter((filePath) => filePath !== 'composite'); + .map((filePath) => filePath.replace('/', '')); const listHtml = storybooks .map((storybook) => `
  • ${storybook}
  • `) @@ -110,8 +107,6 @@ const upload = () => {

    Storybooks

    -

    Composite Storybook

    -

    All

    diff --git a/.ci/.storybook/main.js b/.ci/.storybook/main.js deleted file mode 100644 index c4e017179021..000000000000 --- a/.ci/.storybook/main.js +++ /dev/null @@ -1,34 +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. - */ - -const config = require('@kbn/storybook').defaultConfig; -const aliases = require('../../src/dev/storybook/aliases').storybookAliases; - -config.refs = {}; - -// Required due to https://github.com/storybookjs/storybook/issues/13834 -config.babel = async (options) => ({ - ...options, - plugins: ['@babel/plugin-transform-typescript', ...options.plugins], -}); - -for (const alias of Object.keys(aliases).filter((a) => a !== 'ci_composite')) { - // snake_case -> Title Case - const title = alias - .replace(/_/g, ' ') - .split(' ') - .map((n) => n[0].toUpperCase() + n.slice(1)) - .join(' '); - - config.refs[alias] = { - title: title, - url: `${process.env.STORYBOOK_BASE_URL}/${alias}`, - }; -} - -module.exports = config; diff --git a/.eslintrc.js b/.eslintrc.js index 82193a7e2ecb..23706483a442 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -941,7 +941,7 @@ module.exports = { ], rules: { '@kbn/i18n/strings_should_be_translated_with_i18n': 'warn', - '@kbn/i18n/strings_should_be_translated_with_formatted_message': 'warn', + '@kbn/i18n/i18n_translate_should_start_with_the_right_id': 'warn', }, }, { @@ -1539,6 +1539,17 @@ module.exports = { }, }, + /** + * Serverless Search overrides + */ + { + // All files + files: ['x-pack/plugins/serverless_search/**/*.{ts,tsx}', 'packages/kbn-search-*'], + rules: { + '@kbn/telemetry/event_generating_elements_should_be_instrumented': 'error', + }, + }, + /** * Canvas overrides */ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 994b92442d00..2da7f440baf1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -368,7 +368,7 @@ src/plugins/es_ui_shared @elastic/platform-deployment-management packages/kbn-eslint-config @elastic/kibana-operations packages/kbn-eslint-plugin-disable @elastic/kibana-operations packages/kbn-eslint-plugin-eslint @elastic/kibana-operations -packages/kbn-eslint-plugin-i18n @elastic/obs-knowledge-team +packages/kbn-eslint-plugin-i18n @elastic/obs-knowledge-team @elastic/kibana-operations packages/kbn-eslint-plugin-imports @elastic/kibana-operations packages/kbn-eslint-plugin-telemetry @elastic/obs-knowledge-team x-pack/test/encrypted_saved_objects_api_integration/plugins/api_consumer_plugin @elastic/kibana-security @@ -536,7 +536,9 @@ x-pack/packages/ml/route_utils @elastic/ml-ui x-pack/packages/ml/runtime_field_utils @elastic/ml-ui x-pack/packages/ml/string_hash @elastic/ml-ui x-pack/packages/ml/trained_models_utils @elastic/ml-ui +x-pack/packages/ml/ui_actions @elastic/ml-ui x-pack/packages/ml/url_state @elastic/ml-ui +packages/kbn-mock-idp-plugin @elastic/kibana-security packages/kbn-monaco @elastic/appex-sharedux x-pack/plugins/monitoring_collection @elastic/obs-ux-infra_services-team x-pack/plugins/monitoring @elastic/obs-ux-infra_services-team @@ -751,7 +753,6 @@ test/server_integration/plugins/status_plugin_b @elastic/kibana-core packages/kbn-std @elastic/kibana-core packages/kbn-stdio-dev-helpers @elastic/kibana-operations packages/kbn-storybook @elastic/kibana-operations -packages/kbn-subscription-tracking @elastic/security-threat-hunting-investigations x-pack/plugins/synthetics @elastic/obs-ux-infra_services-team x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture @elastic/response-ops x-pack/test/plugin_api_perf/plugins/task_manager_performance @elastic/response-ops @@ -1394,6 +1395,7 @@ x-pack/test/security_solution_api_integration/test_suites/detections_response/de x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/actions @elastic/security-detection-engine x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/alerts @elastic/security-detection-engine x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/user_roles @elastic/security-detection-engine +x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine @elastic/security-detection-engine /x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users @elastic/security-detection-engine ## Security Threat Intelligence - Under Security Platform @@ -1440,6 +1442,7 @@ x-pack/test/security_solution_api_integration/test_suites/detections_response/de ## Security Solution sub teams - security-telemetry (Data Engineering) x-pack/plugins/security_solution/server/usage/ @elastic/security-data-analytics x-pack/plugins/security_solution/server/lib/telemetry/ @elastic/security-data-analytics +x-pack/test/security_solution_api_integration/test_suites/detections_response/default_license/telemetry @elastic/security-data-analytics ## Security Solution sub teams - security-engineering-productivity /x-pack/test/security_solution_cypress/* @elastic/security-engineering-productivity diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 82678433aacc..64c4d32f35f1 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-11-21 +date: 2023-11-27 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 3066b1334ecc..4c785a0867da 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.devdocs.json b/api_docs/aiops.devdocs.json index 4a976c737c79..6649c83b16df 100644 --- a/api_docs/aiops.devdocs.json +++ b/api_docs/aiops.devdocs.json @@ -573,6 +573,29 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "aiops", + "id": "def-public.AiopsAppDependencies.uiActions", + "type": "Object", + "tags": [], + "label": "uiActions", + "description": [ + "\nUI actions." + ], + "signature": [ + { + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.UiActionsStart", + "text": "UiActionsStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "aiops", "id": "def-public.AiopsAppDependencies.i18n", diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index c14d692c24d5..a54f606decee 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 69 | 1 | 4 | 1 | +| 70 | 1 | 4 | 1 | ## Client diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 9505e1de3807..e80f957ba133 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -7406,12 +7406,15 @@ "parentPluginId": "alerting", "id": "def-common.MaintenanceWindowSOProperties", "type": "Interface", - "tags": [], + "tags": [ + "deprecated" + ], "label": "MaintenanceWindowSOProperties", "description": [], "path": "x-pack/plugins/alerting/common/maintenance_window.ts", - "deprecated": false, + "deprecated": true, "trackAdoption": false, + "references": [], "children": [ { "parentPluginId": "alerting", @@ -7521,6 +7524,21 @@ "path": "x-pack/plugins/alerting/common/maintenance_window.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "alerting", + "id": "def-common.MaintenanceWindowSOProperties.scopedQuery", + "type": "CompoundType", + "tags": [], + "label": "scopedQuery", + "description": [], + "signature": [ + "ScopedQueryAttributes", + " | null | undefined" + ], + "path": "x-pack/plugins/alerting/common/maintenance_window.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -10187,7 +10205,9 @@ "parentPluginId": "alerting", "id": "def-common.MaintenanceWindow", "type": "Type", - "tags": [], + "tags": [ + "deprecated" + ], "label": "MaintenanceWindow", "description": [], "signature": [ @@ -10217,8 +10237,94 @@ "; eventStartTime: string | null; eventEndTime: string | null; id: string; }" ], "path": "x-pack/plugins/alerting/common/maintenance_window.ts", - "deprecated": false, + "deprecated": true, "trackAdoption": false, + "references": [ + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/tooltip_content.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/tooltip_content.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_get_maintenance_windows.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/use_bulk_get_maintenance_windows.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_alert_list.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_alert_list.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_alert_list.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_alert_list.tsx" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/types.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/index.mock.ts" + }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/index.mock.ts" + } + ], "initialIsOpen": false }, { @@ -10237,7 +10343,9 @@ "section": "def-common.RRuleParams", "text": "RRuleParams" }, - "; categoryIds?: string[] | null | undefined; }" + "; categoryIds?: string[] | null | undefined; scopedQuery?: ", + "ScopedQueryAttributes", + " | null | undefined; }" ], "path": "x-pack/plugins/alerting/common/maintenance_window.ts", "deprecated": false, @@ -10263,7 +10371,9 @@ "parentPluginId": "alerting", "id": "def-common.MaintenanceWindowSOAttributes", "type": "Type", - "tags": [], + "tags": [ + "deprecated" + ], "label": "MaintenanceWindowSOAttributes", "description": [], "signature": [ @@ -10284,8 +10394,9 @@ } ], "path": "x-pack/plugins/alerting/common/maintenance_window.ts", - "deprecated": false, + "deprecated": true, "trackAdoption": false, + "references": [], "initialIsOpen": false }, { diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index dbfbad7b56c8..35e5224f252d 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 810 | 1 | 779 | 50 | +| 811 | 1 | 780 | 51 | ## Client diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index 1f8e4fbabe13..0dfa84c0e423 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -597,7 +597,11 @@ "Type", "; endIndex: ", "Type", - "; }>]>; }> | undefined; handler: ({}: ", + "; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>]>; }> | undefined; handler: ({}: ", "APMRouteHandlerResources", " & { params: { path: { serviceName: string; }; query: { start: number; end: number; } & { environment: \"ENVIRONMENT_NOT_DEFINED\" | \"ENVIRONMENT_ALL\" | ", "Branded", @@ -617,7 +621,7 @@ "ApmDocumentType", ".TransactionEvent; rollupInterval: ", "RollupInterval", - "; } & { startIndex: number; endIndex: number; }; }; }) => Promise<{ functions: ", + "; } & { startIndex: number; endIndex: number; } & { kuery: string; }; }; }) => Promise<{ functions: ", { "pluginId": "@kbn/profiling-utils", "scope": "common", @@ -699,7 +703,11 @@ "LiteralC", "<", "RollupInterval", - ".None>]>; }>]>; }> | undefined; handler: ({}: ", + ".None>]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>]>; }> | undefined; handler: ({}: ", "APMRouteHandlerResources", " & { params: { path: { serviceName: string; }; query: { start: number; end: number; } & { environment: \"ENVIRONMENT_NOT_DEFINED\" | \"ENVIRONMENT_ALL\" | ", "Branded", @@ -719,7 +727,7 @@ "ApmDocumentType", ".TransactionEvent; rollupInterval: ", "RollupInterval", - "; }; }; }) => Promise<{ flamegraph: ", + "; } & { kuery: string; }; }; }) => Promise<{ flamegraph: ", { "pluginId": "@kbn/profiling-utils", "scope": "common", @@ -5855,7 +5863,41 @@ "section": "def-common.NonEmptyStringBrand", "text": "NonEmptyStringBrand" }, - ">]>; }>]>; }> | undefined; handler: ({}: ", + ">]>; }>, ", + "TypeC", + "<{ documentType: ", + "UnionC", + "<[", + "LiteralC", + "<", + "ApmDocumentType", + ".ServiceTransactionMetric>, ", + "LiteralC", + "<", + "ApmDocumentType", + ".TransactionMetric>, ", + "LiteralC", + "<", + "ApmDocumentType", + ".TransactionEvent>]>; rollupInterval: ", + "UnionC", + "<[", + "LiteralC", + "<", + "RollupInterval", + ".OneMinute>, ", + "LiteralC", + "<", + "RollupInterval", + ".TenMinutes>, ", + "LiteralC", + "<", + "RollupInterval", + ".SixtyMinutes>, ", + "LiteralC", + "<", + "RollupInterval", + ".None>]>; }>]>; }> | undefined; handler: ({}: ", "APMRouteHandlerResources", " & { params: { path: { serviceName: string; serviceNodeName: string; }; query: { kuery: string; } & { start: number; end: number; } & { environment: \"ENVIRONMENT_NOT_DEFINED\" | \"ENVIRONMENT_ALL\" | ", "Branded", @@ -5867,7 +5909,15 @@ "section": "def-common.NonEmptyStringBrand", "text": "NonEmptyStringBrand" }, - ">; }; }; }) => Promise<", + ">; } & { documentType: ", + "ApmDocumentType", + ".TransactionMetric | ", + "ApmDocumentType", + ".ServiceTransactionMetric | ", + "ApmDocumentType", + ".TransactionEvent; rollupInterval: ", + "RollupInterval", + "; }; }; }) => Promise<", "ServiceNodeMetadataResponse", ">; } & ", "APMRouteCreateOptions", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index b84e7790f9f7..b9021eb002b5 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-11-21 +date: 2023-11-27 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 a737a3aa03cc..809f8c21afda 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-11-21 +date: 2023-11-27 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 c3fd98697b22..d55f11cd8fd6 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-11-21 +date: 2023-11-27 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 e242cf936564..550b553d91c7 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-11-21 +date: 2023-11-27 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 564ea0889cab..c14441a4d8b1 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-11-21 +date: 2023-11-27 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 a527e0f36e93..79384b882350 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-11-21 +date: 2023-11-27 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 4a0be26d524c..2175518b83b8 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-11-21 +date: 2023-11-27 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 f9cc38fc0831..ce5bc2efd59f 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-11-21 +date: 2023-11-27 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 072ea50c708e..4a5e0348815e 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 6ee5118a9f63..fc3f1b6adfdc 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-11-21 +date: 2023-11-27 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 4f48d4c980a4..a6640e58293b 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-11-21 +date: 2023-11-27 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 2f9e2f7f891a..dc98d1f692df 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-11-21 +date: 2023-11-27 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 c918913f93c8..2a6baef1755e 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-11-21 +date: 2023-11-27 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 6ab20e88642c..cb42d5c3df9c 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-11-21 +date: 2023-11-27 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 687bbb3564a0..ec170ede5137 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-11-21 +date: 2023-11-27 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 0e78ff8d63bc..d99580e8b517 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-11-21 +date: 2023-11-27 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 9128f586088e..e9a4c5d3bd82 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-11-21 +date: 2023-11-27 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 a468f244085c..20fd53d59d98 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-11-21 +date: 2023-11-27 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 c3b9a1685c76..3ebdee284f01 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-11-21 +date: 2023-11-27 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 043b2e706493..05273d61198e 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-11-21 +date: 2023-11-27 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 95d6ffb8041d..24918a9b2d9b 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index e929191289b6..fe3f4b793d43 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -267,7 +267,7 @@ "\nCurrent session management\n{@link ISessionService}" ], "signature": [ - "{ start: () => string; save: () => Promise; clear: () => void; destroy: () => void; readonly state$: ", + "{ start: () => string; clear: () => void; save: () => Promise; destroy: () => void; readonly state$: ", "Observable", "<", { @@ -723,7 +723,7 @@ "\nCurrent session management\n{@link ISessionService}" ], "signature": [ - "{ start: () => string; save: () => Promise; clear: () => void; destroy: () => void; readonly state$: ", + "{ start: () => string; clear: () => void; save: () => Promise; destroy: () => void; readonly state$: ", "Observable", "<", { @@ -1279,7 +1279,7 @@ "label": "ISessionService", "description": [], "signature": [ - "{ start: () => string; save: () => Promise; clear: () => void; destroy: () => void; readonly state$: ", + "{ start: () => string; clear: () => void; save: () => Promise; destroy: () => void; readonly state$: ", "Observable", "<", { diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 1ef69eff529d..1153d9278b2b 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-11-21 +date: 2023-11-27 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 6484d822c69a..7f24893ac941 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-11-21 +date: 2023-11-27 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 7e4a49ec9e83..192413dcae23 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-11-21 +date: 2023-11-27 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 6131c415a04a..9627485b6d55 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-11-21 +date: 2023-11-27 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 4f61e3cce929..b655c5a401b3 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-11-21 +date: 2023-11-27 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 8aec0b9b2e31..4e379a7d611e 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.devdocs.json b/api_docs/dataset_quality.devdocs.json index 5b46e39efe55..86ad32dd897c 100644 --- a/api_docs/dataset_quality.devdocs.json +++ b/api_docs/dataset_quality.devdocs.json @@ -5,7 +5,20 @@ "functions": [], "interfaces": [], "enums": [], - "misc": [], + "misc": [ + { + "parentPluginId": "datasetQuality", + "id": "def-public.datasetQualityAppTitle", + "type": "string", + "tags": [], + "label": "datasetQualityAppTitle", + "description": [], + "path": "x-pack/plugins/dataset_quality/common/translations.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], "objects": [], "setup": { "parentPluginId": "datasetQuality", @@ -31,7 +44,22 @@ "path": "x-pack/plugins/dataset_quality/public/types.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "datasetQuality", + "id": "def-public.DatasetQualityPluginStart.DatasetQuality", + "type": "CompoundType", + "tags": [], + "label": "DatasetQuality", + "description": [], + "signature": [ + "React.ComponentClass<{}, any> | React.FunctionComponent<{}>" + ], + "path": "x-pack/plugins/dataset_quality/public/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], "lifecycle": "start", "initialIsOpen": true } @@ -64,6 +92,104 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "datasetQuality", + "id": "def-common.APIClientRequestParamsOf", + "type": "Type", + "tags": [], + "label": "APIClientRequestParamsOf", + "description": [], + "signature": [ + "{ \"GET /internal/dataset_quality/data_streams/stats\": { endpoint: \"GET /internal/dataset_quality/data_streams/stats\"; params?: ", + "TypeC", + "<{ query: ", + "IntersectionC", + "<[", + "PartialC", + "<{ type: ", + "UnionC", + "<[", + "LiteralC", + "<\"logs\">, ", + "LiteralC", + "<\"metrics\">, ", + "LiteralC", + "<\"traces\">, ", + "LiteralC", + "<\"synthetics\">, ", + "LiteralC", + "<\"profiling\">]>; }>, ", + "PartialC", + "<{ datasetQuery: ", + "StringC", + "; }>]>; }> | undefined; handler: ({}: ", + "DatasetQualityRouteHandlerResources", + " & { params: { query: { type?: \"metrics\" | \"synthetics\" | \"profiling\" | \"traces\" | \"logs\" | undefined; } & { datasetQuery?: string | undefined; }; }; }) => Promise<", + "DataStreamsStatResponse", + ">; } & ", + "DatasetQualityRouteCreateOptions", + "; }[TEndpoint] extends { endpoint: any; params?: infer TRouteParamsRT | undefined; handler: ({}: any) => Promise; } & ", + "ServerRouteCreateOptions", + " ? TRouteParamsRT extends ", + { + "pluginId": "@kbn/server-route-repository", + "scope": "common", + "docId": "kibKbnServerRouteRepositoryPluginApi", + "section": "def-common.RouteParamsRT", + "text": "RouteParamsRT" + }, + " ? ClientRequestParamsOfType : {} : never" + ], + "path": "x-pack/plugins/dataset_quality/common/rest/create_call_dataset_quality_api.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "datasetQuality", + "id": "def-common.APIReturnType", + "type": "Type", + "tags": [], + "label": "APIReturnType", + "description": [], + "signature": [ + "{ \"GET /internal/dataset_quality/data_streams/stats\": { endpoint: \"GET /internal/dataset_quality/data_streams/stats\"; params?: ", + "TypeC", + "<{ query: ", + "IntersectionC", + "<[", + "PartialC", + "<{ type: ", + "UnionC", + "<[", + "LiteralC", + "<\"logs\">, ", + "LiteralC", + "<\"metrics\">, ", + "LiteralC", + "<\"traces\">, ", + "LiteralC", + "<\"synthetics\">, ", + "LiteralC", + "<\"profiling\">]>; }>, ", + "PartialC", + "<{ datasetQuery: ", + "StringC", + "; }>]>; }> | undefined; handler: ({}: ", + "DatasetQualityRouteHandlerResources", + " & { params: { query: { type?: \"metrics\" | \"synthetics\" | \"profiling\" | \"traces\" | \"logs\" | undefined; } & { datasetQuery?: string | undefined; }; }; }) => Promise<", + "DataStreamsStatResponse", + ">; } & ", + "DatasetQualityRouteCreateOptions", + "; }[TEndpoint] extends { endpoint: any; params?: any; handler: ({}: any) => Promise; } & ", + "ServerRouteCreateOptions", + " ? TReturnType : never" + ], + "path": "x-pack/plugins/dataset_quality/common/rest/create_call_dataset_quality_api.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "datasetQuality", "id": "def-common.FetchOptions", diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index fd897f93822a..a674a78cc259 100644 --- a/api_docs/dataset_quality.mdx +++ b/api_docs/dataset_quality.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/datasetQuality title: "datasetQuality" image: https://source.unsplash.com/400x175/?github description: API docs for the datasetQuality plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'datasetQuality'] --- import datasetQualityObj from './dataset_quality.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 4 | 0 | 4 | 0 | +| 8 | 0 | 8 | 3 | ## Client @@ -31,6 +31,9 @@ Contact [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux ### Start +### Consts, variables and types + + ## Common ### Interfaces diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 76ed656e45c0..2a8359bcba49 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -27,9 +27,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | stackAlerts, graph, infra, inputControlVis, securitySolution, savedObjects | - | | | dashboard, dataVisualizer, stackAlerts, expressionPartitionVis | - | | | stackAlerts, alerting, securitySolution, inputControlVis | - | +| | triggersActionsUi | - | +| | inspector, data, savedObjects, runtimeFields, indexManagement, dataViewEditor, unifiedSearch, embeddable, visualizations, controls, dashboard, licensing, savedObjectsTagging, dataViewFieldEditor, lens, security, triggersActionsUi, cases, observabilityShared, advancedSettings, exploratoryView, fleet, telemetry, maps, banners, reporting, timelines, cloudSecurityPosture, dashboardEnhanced, imageEmbeddable, graph, monitoring, securitySolution, synthetics, uptime, cloudLinks, console, dataViewManagement, eventAnnotationListing, filesManagement, uiActions, visTypeVislib | - | +| | @kbn/core, visualizations, triggersActionsUi, advancedSettings | - | | | observability, @kbn/securitysolution-data-table, securitySolution | - | | | monitoring | - | -| | inspector, data, savedObjects, runtimeFields, indexManagement, dataViewEditor, unifiedSearch, embeddable, visualizations, controls, dashboard, licensing, savedObjectsTagging, dataViewFieldEditor, lens, security, triggersActionsUi, cases, observabilityShared, advancedSettings, exploratoryView, fleet, telemetry, maps, banners, reporting, timelines, cloudSecurityPosture, dashboardEnhanced, imageEmbeddable, graph, monitoring, securitySolution, synthetics, uptime, cloudLinks, console, dataViewManagement, eventAnnotationListing, filesManagement, uiActions, visTypeVislib | - | | | alerting, discover, securitySolution | - | | | @kbn/core-saved-objects-api-browser, @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-api-server-internal, @kbn/core-saved-objects-import-export-server-internal, @kbn/core-saved-objects-server-internal, fleet, graph, lists, osquery, securitySolution, alerting | - | | | @kbn/core-saved-objects-api-browser, @kbn/core-saved-objects-browser-internal, @kbn/core-saved-objects-browser-mocks, @kbn/core-saved-objects-api-server-internal, @kbn/core-saved-objects-import-export-server-internal, @kbn/core-saved-objects-server-internal, fleet, graph, lists, osquery, securitySolution, alerting | - | @@ -122,7 +124,6 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | canvas | - | | | canvas | - | | | spaces, savedObjectsManagement | - | -| | @kbn/core, visualizations, triggersActionsUi, advancedSettings | - | | | reporting | - | | | @kbn/reporting-export-types-pdf, reporting | - | | | @kbn/core-elasticsearch-server-internal, @kbn/core-plugins-server-internal, observabilityOnboarding, console | - | @@ -164,6 +165,8 @@ Safe to remove. | Deprecated API | Plugin Id | | ---------------|------------| | | alerting | +| | alerting | +| | alerting | | | data | | | data | | | data | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 498a4fe745f1..ab5c0b0fabbc 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -1488,6 +1488,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [tooltip_content.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/tooltip_content.tsx#:~:text=MaintenanceWindow), [tooltip_content.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/tooltip_content.tsx#:~:text=MaintenanceWindow), [cell.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx#:~:text=MaintenanceWindow), [cell.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx#:~:text=MaintenanceWindow), [cell.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx#:~:text=MaintenanceWindow), [cell.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/maintenance_windows/cell.tsx#:~:text=MaintenanceWindow), [bulk_get_maintenance_windows.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts#:~:text=MaintenanceWindow), [bulk_get_maintenance_windows.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts#:~:text=MaintenanceWindow), [bulk_get_maintenance_windows.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts#:~:text=MaintenanceWindow), [bulk_get_maintenance_windows.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_table/hooks/apis/bulk_get_maintenance_windows.ts#:~:text=MaintenanceWindow)+ 11 more | - | | | [use_bulk_edit_response.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_response.tsx#:~:text=toMountPoint), [use_bulk_edit_response.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_response.tsx#:~:text=toMountPoint), [use_bulk_edit_response.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_edit_response.tsx#:~:text=toMountPoint), [use_bulk_operation_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_operation_toast.tsx#:~:text=toMountPoint), [use_bulk_operation_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_operation_toast.tsx#:~:text=toMountPoint), [use_bulk_operation_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_bulk_operation_toast.tsx#:~:text=toMountPoint), [rule_add.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx#:~:text=toMountPoint), [rule_add.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx#:~:text=toMountPoint), [rule_edit.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx#:~:text=toMountPoint), [rule_edit.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx#:~:text=toMountPoint)+ 6 more | - | | | [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/app.tsx#:~:text=KibanaThemeProvider), [connectors_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx#:~:text=KibanaThemeProvider), [connectors_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx#:~:text=KibanaThemeProvider), [connectors_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx#:~:text=KibanaThemeProvider), [test_utils.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx#:~:text=KibanaThemeProvider), [test_utils.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx#:~:text=KibanaThemeProvider), [test_utils.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/test_utils.tsx#:~:text=KibanaThemeProvider) | - | | | [rule_reducer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts#:~:text=SavedObjectAttribute), [rule_reducer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts#:~:text=SavedObjectAttribute), [rule_reducer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts#:~:text=SavedObjectAttribute), [rule_reducer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts#:~:text=SavedObjectAttribute) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 7804abf2afe5..b12acd1a4ec1 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index e09ade406537..853d9f2547e2 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-11-21 +date: 2023-11-27 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 1345ef75ad6a..1a4c534c5d80 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.devdocs.json b/api_docs/discover_enhanced.devdocs.json index 2a08df38909f..f0194c72301a 100644 --- a/api_docs/discover_enhanced.devdocs.json +++ b/api_docs/discover_enhanced.devdocs.json @@ -639,15 +639,15 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -663,15 +663,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; }" + ") => void; }" ], "path": "x-pack/plugins/discover_enhanced/public/plugin.ts", "deprecated": false, @@ -760,15 +760,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -784,17 +786,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index d557ebe34a18..696c8660dbf5 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-11-21 +date: 2023-11-27 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 44f3dcdddecc..4fefcb3b2c16 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-11-21 +date: 2023-11-27 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 34dd65504fd9..7b8440900fb1 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'elasticAssistant'] --- import elasticAssistantObj from './elastic_assistant.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index b898e64c67d2..426bbd6909c6 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -7675,15 +7675,15 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -7699,15 +7699,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; }" + ") => void; }" ], "path": "src/plugins/embeddable/public/plugin.tsx", "deprecated": false, @@ -7735,15 +7735,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -7759,17 +7761,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 50e7440f4138..b4080118f2eb 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-11-21 +date: 2023-11-27 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 de533bfb6a1e..35b9f9bd825e 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-11-21 +date: 2023-11-27 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 051d9e2f093e..f45196630b9f 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-11-21 +date: 2023-11-27 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 79083831bd70..c8fd1dc1e760 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-11-21 +date: 2023-11-27 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 00276211783b..b22d8267fba2 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-11-21 +date: 2023-11-27 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 3bdc056cfc18..20050fd23c1b 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-11-21 +date: 2023-11-27 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 ad63fbc3e4fb..fe5e20213bb1 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-11-21 +date: 2023-11-27 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 958b808a5023..0bf739bda484 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-11-21 +date: 2023-11-27 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 9baad8ed30a7..9a5d0457f7d0 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-11-21 +date: 2023-11-27 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 cd5534e73bd6..d1f88e781ee6 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-11-21 +date: 2023-11-27 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 1871f53f5df4..d10c9d59893c 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-11-21 +date: 2023-11-27 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 e5b047559483..563fc6e02849 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-11-21 +date: 2023-11-27 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 db8a9d719a41..45d26f6f71e9 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-11-21 +date: 2023-11-27 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 72e1fe6f37c8..232fae505126 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-11-21 +date: 2023-11-27 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 bc0e4be2e99b..1ffa2b80760d 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-11-21 +date: 2023-11-27 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 0416ed3733bd..10f8b604648c 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-11-21 +date: 2023-11-27 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 2448a4e0b471..b2d950c1cbbb 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-11-21 +date: 2023-11-27 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 114eabcf97d5..38428d4b10a7 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-11-21 +date: 2023-11-27 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 24b09175b58b..bfa49b6cb0b8 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-11-21 +date: 2023-11-27 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 7d85211b4ad1..e9981ec0a962 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-11-21 +date: 2023-11-27 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 3b39a6143689..c981ba192e68 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-11-21 +date: 2023-11-27 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 1ae39611bd16..3ce13d601263 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-11-21 +date: 2023-11-27 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 736777d1ac78..eea81fe45852 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-11-21 +date: 2023-11-27 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 7e26df9d8ab0..3a326f4eb73c 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-11-21 +date: 2023-11-27 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 6a2758ad6bbc..85ad4da1539e 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-11-21 +date: 2023-11-27 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 9dcda19534d6..6bf50fc358ac 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-11-21 +date: 2023-11-27 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 465df5bdefa8..78895c44ec16 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-11-21 +date: 2023-11-27 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 c90273857278..748a56e2297a 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-11-21 +date: 2023-11-27 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 1744f38c82da..d65c36e26e38 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-11-21 +date: 2023-11-27 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 4a554a725fff..8ad168e34270 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-11-21 +date: 2023-11-27 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 ac7d8013ba6d..ce7999046094 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-11-21 +date: 2023-11-27 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 c4208655916d..92b55ad21bc9 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-11-21 +date: 2023-11-27 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 e49f3b037770..c928583a2291 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-11-21 +date: 2023-11-27 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 c96652dc1d2f..ec776a6d62a5 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-11-21 +date: 2023-11-27 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 2639af5535e1..611a638958fe 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-11-21 +date: 2023-11-27 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 71420826df6d..37023530f2a1 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-11-21 +date: 2023-11-27 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 9660dc20f7aa..df3d703fd9d8 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-11-21 +date: 2023-11-27 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 288958199e0b..d971d928917d 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-11-21 +date: 2023-11-27 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 30af81a5a462..c9d0a05702cb 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-11-21 +date: 2023-11-27 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 498d8b80579c..528f1303d21c 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.devdocs.json b/api_docs/kbn_aiops_utils.devdocs.json index 4ab34fcaf1db..b733fd1318ca 100644 --- a/api_docs/kbn_aiops_utils.devdocs.json +++ b/api_docs/kbn_aiops_utils.devdocs.json @@ -336,12 +336,10 @@ "parentPluginId": "@kbn/aiops-utils", "id": "def-common.WindowParameters.baselineMin", "type": "number", - "tags": [ - "type" - ], + "tags": [], "label": "baselineMin", "description": [ - "\nBaseline minimum value" + "Baseline minimum value" ], "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, @@ -351,12 +349,10 @@ "parentPluginId": "@kbn/aiops-utils", "id": "def-common.WindowParameters.baselineMax", "type": "number", - "tags": [ - "type" - ], + "tags": [], "label": "baselineMax", "description": [ - "\nBaseline maximum value" + "Baseline maximum value" ], "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, @@ -366,12 +362,10 @@ "parentPluginId": "@kbn/aiops-utils", "id": "def-common.WindowParameters.deviationMin", "type": "number", - "tags": [ - "type" - ], + "tags": [], "label": "deviationMin", "description": [ - "\nDeviation minimum value" + "Deviation minimum value" ], "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, @@ -381,12 +375,10 @@ "parentPluginId": "@kbn/aiops-utils", "id": "def-common.WindowParameters.deviationMax", "type": "number", - "tags": [ - "type" - ], + "tags": [], "label": "deviationMax", "description": [ - "\nDeviation maximum value" + "Deviation maximum value" ], "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index fe5916c30c0d..f45a22752313 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-11-21 +date: 2023-11-27 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 02bcc50aa26e..b6e93757c6b3 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-11-21 +date: 2023-11-27 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 91edd2d33adb..5fa02845e48a 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-11-21 +date: 2023-11-27 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 3920ff3bc198..b79c113c8204 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-11-21 +date: 2023-11-27 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 57fe755400e5..66ee126b1aaa 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-11-21 +date: 2023-11-27 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 accc966ceea3..9b8e645857f9 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.devdocs.json b/api_docs/kbn_analytics_client.devdocs.json index 2fd0a65a4ff2..08766a1c077d 100644 --- a/api_docs/kbn_analytics_client.devdocs.json +++ b/api_docs/kbn_analytics_client.devdocs.json @@ -718,14 +718,6 @@ "plugin": "dashboard", "path": "src/plugins/dashboard/public/services/analytics/analytics_service.ts" }, - { - "plugin": "@kbn/subscription-tracking", - "path": "packages/kbn-subscription-tracking/src/use_go_to_subscription.ts" - }, - { - "plugin": "@kbn/subscription-tracking", - "path": "packages/kbn-subscription-tracking/src/use_impression.ts" - }, { "plugin": "fleet", "path": "x-pack/plugins/fleet/server/services/telemetry/fleet_usage_sender.ts" diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index d4c0814d1c56..5b8af2726d88 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 1846fc4942b7..eab9eca71d37 100644 --- a/api_docs/kbn_analytics_collection_utils.mdx +++ b/api_docs/kbn_analytics_collection_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-collection-utils title: "@kbn/analytics-collection-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-collection-utils plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.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 dd63b24dc096..03cffafba4a2 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-11-21 +date: 2023-11-27 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 9d182ee6d94c..659b783fc5f3 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-11-21 +date: 2023-11-27 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 4d3308bc23b7..60e1c41062ec 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_analytics_shippers_fullstory.devdocs.json index 7a55836c7d02..5878e65af7ef 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.devdocs.json +++ b/api_docs/kbn_analytics_shippers_fullstory.devdocs.json @@ -288,7 +288,7 @@ "tags": [], "label": "shutdown", "description": [ - "\nShuts down the shipper.\nIt doesn't really do anything inside because this shipper doesn't hold any internal queues." + "\nShuts down the shipper." ], "signature": [ "() => void" @@ -350,6 +350,20 @@ "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/analytics-shippers-fullstory", + "id": "def-common.FullStoryShipperConfig.pageVarsDebounceTimeMs", + "type": "number", + "tags": [], + "label": "pageVarsDebounceTimeMs", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "packages/analytics/shippers/fullstory/src/fullstory_shipper.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 0ea6ed98e604..adb745424930 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 21 | 0 | 0 | 0 | +| 22 | 0 | 1 | 0 | ## Common diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 1221a9199f66..8ff38bbef417 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-11-21 +date: 2023-11-27 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 686fe0d0533e..7ae1be487e79 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-11-21 +date: 2023-11-27 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 5ed1cfcf9888..bd4e16926259 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-11-21 +date: 2023-11-27 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 ba5f775a98c3..77c1ea266b35 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-11-21 +date: 2023-11-27 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 57489e78c1b6..036736bc17e1 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-11-21 +date: 2023-11-27 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 73c4e9152153..4fb585f8ebb7 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_calculate_auto.mdx b/api_docs/kbn_calculate_auto.mdx index 70b638105ee8..8e0909592b33 100644 --- a/api_docs/kbn_calculate_auto.mdx +++ b/api_docs/kbn_calculate_auto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-calculate-auto title: "@kbn/calculate-auto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/calculate-auto plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/calculate-auto'] --- import kbnCalculateAutoObj from './kbn_calculate_auto.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index f43cf678c8dd..3bea56c9ca0c 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-11-21 +date: 2023-11-27 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 a224c6e8146b..1acab6744b7a 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-11-21 +date: 2023-11-27 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 926ae27abf34..9a043b9134c7 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-11-21 +date: 2023-11-27 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 6cb6794ed965..05d682dba70c 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-11-21 +date: 2023-11-27 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 6d47fa7420b1..ab8affb9735c 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-11-21 +date: 2023-11-27 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 f63c9323776a..abe3c18176b2 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-11-21 +date: 2023-11-27 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 f9cad5f3e1e5..3f1d9c165713 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-11-21 +date: 2023-11-27 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 c0bde54f9b81..1cd1a633b6ba 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-11-21 +date: 2023-11-27 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 3609f6ff3145..3c18329d587f 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 62279636192b..89d181029846 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-11-21 +date: 2023-11-27 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 8a6252e8bc17..8a6a9cba88e8 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.devdocs.json b/api_docs/kbn_config_mocks.devdocs.json index 29e17d650004..c470bc5513b2 100644 --- a/api_docs/kbn_config_mocks.devdocs.json +++ b/api_docs/kbn_config_mocks.devdocs.json @@ -310,7 +310,7 @@ }, "[]][], [], unknown>; atPath: jest.MockInstance<", "Observable", - ", [path: ", + ", [", { "pluginId": "@kbn/config", "scope": "common", @@ -318,7 +318,7 @@ "section": "def-common.ConfigPath", "text": "ConfigPath" }, - "], unknown>; atPathSync: jest.MockInstance; atPathSync: jest.MockInstance Promise<", + "({ config$, executionContext, }: ", + "HttpServerSetupOptions", + ") => Promise<", "HttpServerSetup", ">" ], @@ -716,37 +708,15 @@ "id": "def-common.HttpServer.setup.$1", "type": "Object", "tags": [], - "label": "config", + "label": "{\n config$,\n executionContext,\n }", "description": [], "signature": [ - { - "pluginId": "@kbn/core-http-server-internal", - "scope": "common", - "docId": "kibKbnCoreHttpServerInternalPluginApi", - "section": "def-common.HttpConfig", - "text": "HttpConfig" - } + "HttpServerSetupOptions" ], "path": "packages/core/http/core-http-server-internal/src/http_server.ts", "deprecated": false, "trackAdoption": false, "isRequired": true - }, - { - "parentPluginId": "@kbn/core-http-server-internal", - "id": "def-common.HttpServer.setup.$2", - "type": "Object", - "tags": [], - "label": "executionContext", - "description": [], - "signature": [ - "IExecutionContext", - " | undefined" - ], - "path": "packages/core/http/core-http-server-internal/src/http_server.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": false } ], "returnComment": [] diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index d52f85a688a1..4e6d6c8ea2cd 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 59 | 0 | 53 | 8 | +| 58 | 0 | 52 | 9 | ## Common diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 244728d0db23..87d235a9f8fd 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-11-21 +date: 2023-11-27 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 f20b13be73b1..52484b107acd 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-11-21 +date: 2023-11-27 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 14203627e864..7ed630e2b8c7 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-11-21 +date: 2023-11-27 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 21a460bedc49..6478f1efdf94 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-11-21 +date: 2023-11-27 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 7a93bddca8c0..8e718fea0f47 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-11-21 +date: 2023-11-27 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 270aaa1923d4..1f56ffbbaaed 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-11-21 +date: 2023-11-27 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 e6698ca132b1..105bc78cbc63 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-11-21 +date: 2023-11-27 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 63088b8e229c..c9b28fbbf1c3 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-11-21 +date: 2023-11-27 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 fc9c382e955b..547d3c712b75 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-11-21 +date: 2023-11-27 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 7747b1cb5305..596d7339adb9 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-11-21 +date: 2023-11-27 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 4fde81e43932..341b14928e80 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-11-21 +date: 2023-11-27 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 c00b4be0ed2c..9d45812f0f5c 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-11-21 +date: 2023-11-27 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 a903c8f0dc29..ff84dd07f48d 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-11-21 +date: 2023-11-27 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 950ed3746892..de35509c4ea2 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-11-21 +date: 2023-11-27 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 13e258dc2ca7..20b9dbfd2d37 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-11-21 +date: 2023-11-27 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 16b640036d70..e6c50ffc61d0 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-11-21 +date: 2023-11-27 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 044ad95e9350..96525c27ed62 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-11-21 +date: 2023-11-27 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 f8d000cd6df1..1a935e2df3ff 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-11-21 +date: 2023-11-27 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 41a8e2cad0d3..961c0d6e7b01 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-11-21 +date: 2023-11-27 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 5f59371d7fa1..98ab36e03ea1 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-11-21 +date: 2023-11-27 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 299a13ed365c..85212aa238a4 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-11-21 +date: 2023-11-27 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 ed8a8a74a053..52264d1cb91f 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-11-21 +date: 2023-11-27 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 9b9823d00540..c423b1cabeb6 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-11-21 +date: 2023-11-27 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 30d25035043b..d4264d3c5621 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-11-21 +date: 2023-11-27 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 3e1f5c0c2729..0eff86b9aa99 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-11-21 +date: 2023-11-27 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 7c5db2154744..d52f863ed046 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-11-21 +date: 2023-11-27 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 efd9b5fbbfec..22786b6970d3 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-11-21 +date: 2023-11-27 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 fa45a22c1d4a..2f0a99a95c7c 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-11-21 +date: 2023-11-27 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 4b68cf74c1be..fd3e4a6710e0 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-11-21 +date: 2023-11-27 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 5517b4059319..d57b4b10eac0 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-11-21 +date: 2023-11-27 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 57e71cb66b71..b6c5fc996c7a 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-11-21 +date: 2023-11-27 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 23e2fcc52f76..a2b6d90ff72a 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-11-21 +date: 2023-11-27 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 b513a6a0210b..ccc6b2416d5d 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-11-21 +date: 2023-11-27 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 80f96840b3a5..7905d0fba4e3 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-11-21 +date: 2023-11-27 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 653a2a64fa70..5e6226ed5f33 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_browser.mdx b/api_docs/kbn_core_plugins_contracts_browser.mdx index 1249b549641b..11f772f5feb1 100644 --- a/api_docs/kbn_core_plugins_contracts_browser.mdx +++ b/api_docs/kbn_core_plugins_contracts_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-browser title: "@kbn/core-plugins-contracts-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-browser plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-browser'] --- import kbnCorePluginsContractsBrowserObj from './kbn_core_plugins_contracts_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_contracts_server.mdx b/api_docs/kbn_core_plugins_contracts_server.mdx index 2cb14668eeea..3b2799bb0639 100644 --- a/api_docs/kbn_core_plugins_contracts_server.mdx +++ b/api_docs/kbn_core_plugins_contracts_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-contracts-server title: "@kbn/core-plugins-contracts-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-contracts-server plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-contracts-server'] --- import kbnCorePluginsContractsServerObj from './kbn_core_plugins_contracts_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 0d7e55ef7fa2..93272c2ea58c 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-11-21 +date: 2023-11-27 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 944d0697e3b8..c956ce575b04 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-11-21 +date: 2023-11-27 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 aec40c6dce20..a5e8ee01f4db 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-11-21 +date: 2023-11-27 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 bdfb9e4732c0..fcfed80eb01e 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-11-21 +date: 2023-11-27 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 7379d7314fd7..47e45bfb9e1f 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-11-21 +date: 2023-11-27 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 7af41059a032..3101f4200bf2 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-11-21 +date: 2023-11-27 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 db90a4d6ba31..089772ede243 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-11-21 +date: 2023-11-27 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 ad0186fed104..56e01c8eac8f 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-11-21 +date: 2023-11-27 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 1a07fde364f1..5fe79228b438 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-11-21 +date: 2023-11-27 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 21939150e979..0c294493aae0 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-11-21 +date: 2023-11-27 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 4345d0e2cbd0..36400f64e4b0 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-11-21 +date: 2023-11-27 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 7e352ef3cf4c..2b47d5bd7783 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-11-21 +date: 2023-11-27 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 220d3b99b512..8755a1f005a7 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-11-21 +date: 2023-11-27 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 53c2af1ea447..6194164b638f 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-11-21 +date: 2023-11-27 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 94af7e2ad037..74b66e3b9913 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-11-21 +date: 2023-11-27 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 45bfa55afa0b..78684025efc3 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-11-21 +date: 2023-11-27 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 141e41a7ac6a..abd590cd0397 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-11-21 +date: 2023-11-27 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 8695a33b845d..cfada81330a9 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-11-21 +date: 2023-11-27 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 76c484025c00..a713f479d27e 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-11-21 +date: 2023-11-27 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 2b10c291ca69..daff07821d99 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-11-21 +date: 2023-11-27 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 3e4da598757d..ed994357aba4 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-11-21 +date: 2023-11-27 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 87b5b6fd05dd..b715ccd14274 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-11-21 +date: 2023-11-27 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 b52ebd3690a5..9db58dd7e037 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-11-21 +date: 2023-11-27 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 0374715542eb..8adedbc4daf2 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-11-21 +date: 2023-11-27 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 2786fb415d2a..82c212b119c6 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-11-21 +date: 2023-11-27 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 f322fac4c93f..910d8ae6211e 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-11-21 +date: 2023-11-27 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 39254035d3ec..50f52f3edbe5 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-11-21 +date: 2023-11-27 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 7a4fbe9be16c..e78779057612 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-11-21 +date: 2023-11-27 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 9f0909d8c8cb..91a0158a9ecd 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-11-21 +date: 2023-11-27 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 e97e9105b6b3..fbb27d997253 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-11-21 +date: 2023-11-27 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 4e7d764fef73..cf1b2f923170 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-11-21 +date: 2023-11-27 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 8ed48b359e56..c1f88acd65ea 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-11-21 +date: 2023-11-27 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 664d859671cf..1135ad8fb596 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_model_versions.mdx b/api_docs/kbn_core_test_helpers_model_versions.mdx index 9df89898c6b2..643c319e2a3d 100644 --- a/api_docs/kbn_core_test_helpers_model_versions.mdx +++ b/api_docs/kbn_core_test_helpers_model_versions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-model-versions title: "@kbn/core-test-helpers-model-versions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-model-versions plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-model-versions'] --- import kbnCoreTestHelpersModelVersionsObj from './kbn_core_test_helpers_model_versions.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 6e6e0657bcfa..83eba804369b 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-11-21 +date: 2023-11-27 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 fc47046cc49a..3047aec23c93 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-11-21 +date: 2023-11-27 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 6cd018970831..5be6e6d57e67 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-11-21 +date: 2023-11-27 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 875904cd6ff0..84fc637370df 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-11-21 +date: 2023-11-27 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 473388766ad7..09870c2fa7e1 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-11-21 +date: 2023-11-27 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 50f0f34e9ca6..5025ee6bb0f6 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-11-21 +date: 2023-11-27 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 c50893861738..c410be1ceba3 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-11-21 +date: 2023-11-27 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 d43b7d6dd115..4d2fcf705ec0 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-11-21 +date: 2023-11-27 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 48680842fbb9..89976c832607 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-11-21 +date: 2023-11-27 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 76cb0ea66e0b..33ff2fc46428 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-11-21 +date: 2023-11-27 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 f89be556c953..1013ee4c0cbb 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-11-21 +date: 2023-11-27 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 540440835840..0efaf11644fd 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-11-21 +date: 2023-11-27 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 ddd3619d913f..c23d8db9377f 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-11-21 +date: 2023-11-27 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 46d50523cf97..96b6f9ea624a 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-11-21 +date: 2023-11-27 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 ea81db9b5bc5..2a9a35267855 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-11-21 +date: 2023-11-27 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 9140b5058ddb..eb4e746ea095 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-11-21 +date: 2023-11-27 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 91ba8ef78cf3..ce431e25e306 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-11-21 +date: 2023-11-27 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 bb4e27dbdc21..a7165f9876f2 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-11-21 +date: 2023-11-27 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 9473e6ef4e7d..cbc8889329c8 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_custom_icons.mdx b/api_docs/kbn_custom_icons.mdx index a530c63b54ce..c49c3ed16647 100644 --- a/api_docs/kbn_custom_icons.mdx +++ b/api_docs/kbn_custom_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-custom-icons title: "@kbn/custom-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/custom-icons plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/custom-icons'] --- import kbnCustomIconsObj from './kbn_custom_icons.devdocs.json'; diff --git a/api_docs/kbn_custom_integrations.mdx b/api_docs/kbn_custom_integrations.mdx index 9bd7f13098f0..1327df35c3f9 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-11-21 +date: 2023-11-27 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 c475e84616e8..84a83f48f4e5 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-11-21 +date: 2023-11-27 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 dafcb8cc1ca2..dd3045cfc7a7 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-11-21 +date: 2023-11-27 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 f7261735ec03..0ce599d64ea8 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-11-21 +date: 2023-11-27 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 2c5af8a45f1b..6a5ef4d07650 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-11-21 +date: 2023-11-27 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 a38d853a60d4..1802c464d64f 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-11-21 +date: 2023-11-27 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 76c725964ca1..6d504a94b89b 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-11-21 +date: 2023-11-27 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 5348a11f084b..8cfa53ca4243 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-11-21 +date: 2023-11-27 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 e9bc7f0f987e..757e26b3d085 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-11-21 +date: 2023-11-27 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 5c8c6e826fba..b99d47e97914 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-11-21 +date: 2023-11-27 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 5e25be6d1e5d..ac3729e66242 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-11-21 +date: 2023-11-27 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 274bdac28042..9c164b6ce0e9 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-11-21 +date: 2023-11-27 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 124d5f509930..84a171eea9a2 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-11-21 +date: 2023-11-27 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 510f1601fdd7..3fdee1b5fc47 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-11-21 +date: 2023-11-27 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 154ca5c93227..9cff77751cdf 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-11-21 +date: 2023-11-27 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 9de640d5709a..c14a521a7327 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-11-21 +date: 2023-11-27 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 adfc178275a9..344218d9b760 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-11-21 +date: 2023-11-27 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 dcd983d3ceb0..bd7ce85ebd75 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-11-21 +date: 2023-11-27 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 693ffd9fc197..4a483c4cd98f 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index d79272c54bcf..d621bb6b27a6 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -840,7 +840,7 @@ "label": "fleet", "description": [], "signature": [ - "{ readonly beatsAgentComparison: string; readonly guide: string; readonly fleetServer: string; readonly fleetServerAddFleetServer: string; readonly esSettings: string; readonly settings: string; readonly logstashSettings: string; readonly kafkaSettings: string; readonly settingsFleetServerHostSettings: string; readonly settingsFleetServerProxySettings: string; readonly troubleshooting: string; readonly elasticAgent: string; readonly datastreams: string; readonly datastreamsILM: string; readonly datastreamsNamingScheme: string; readonly datastreamsManualRollover: string; readonly datastreamsTSDS: string; readonly datastreamsTSDSMetrics: string; readonly installElasticAgent: string; readonly installElasticAgentStandalone: string; readonly packageSignatures: string; readonly upgradeElasticAgent: string; readonly learnMoreBlog: string; readonly apiKeysLearnMore: string; readonly onPremRegistry: string; readonly secureLogstash: string; readonly agentPolicy: string; readonly api: string; readonly uninstallAgent: string; readonly installAndUninstallIntegrationAssets: string; readonly elasticAgentInputConfiguration: string; readonly policySecrets: string; }" + "{ readonly beatsAgentComparison: string; readonly guide: string; readonly fleetServer: string; readonly fleetServerAddFleetServer: string; readonly esSettings: string; readonly settings: string; readonly logstashSettings: string; readonly kafkaSettings: string; readonly settingsFleetServerHostSettings: string; readonly settingsFleetServerProxySettings: string; readonly troubleshooting: string; readonly elasticAgent: string; readonly datastreams: string; readonly datastreamsILM: string; readonly datastreamsNamingScheme: string; readonly datastreamsManualRollover: string; readonly datastreamsTSDS: string; readonly datastreamsTSDSMetrics: string; readonly installElasticAgent: string; readonly installElasticAgentStandalone: string; readonly packageSignatures: string; readonly upgradeElasticAgent: string; readonly learnMoreBlog: string; readonly apiKeysLearnMore: string; readonly onPremRegistry: string; readonly secureLogstash: string; readonly agentPolicy: string; readonly api: string; readonly uninstallAgent: string; readonly installAndUninstallIntegrationAssets: string; readonly elasticAgentInputConfiguration: string; readonly policySecrets: string; readonly remoteESOoutput: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 421f67945b04..80f52eccfc2c 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-11-21 +date: 2023-11-27 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 42347b3f85b0..6088ceeb5c45 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-11-21 +date: 2023-11-27 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 76a5ecbf01a1..266ab3853065 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-11-21 +date: 2023-11-27 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 97065406dcbc..2401374909e4 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-11-21 +date: 2023-11-27 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 91447abe9e29..3a804b93f01e 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-11-21 +date: 2023-11-27 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 4110be8a06e8..ea0e3034d00b 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index f96d2d23ad4f..2dca4abc65a1 100644 --- a/api_docs/kbn_elastic_agent_utils.mdx +++ b/api_docs/kbn_elastic_agent_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-agent-utils title: "@kbn/elastic-agent-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-agent-utils plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-agent-utils'] --- import kbnElasticAgentUtilsObj from './kbn_elastic_agent_utils.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 486a464a743c..ac984b73af80 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-11-21 +date: 2023-11-27 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 4d715135fc15..efdb5cf0aefb 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-11-21 +date: 2023-11-27 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 3adc0ff6f356..b4f624292fec 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-11-21 +date: 2023-11-27 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 80a922840dbd..d8b37010acfa 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-11-21 +date: 2023-11-27 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 b37e32f1b392..5fcfa1b4bb7b 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-11-21 +date: 2023-11-27 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 84dafa401b1f..3d1fc27db30b 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-11-21 +date: 2023-11-27 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 8efe7adb4418..ad2143a75401 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-11-21 +date: 2023-11-27 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 4580d05fb467..83482cf5c22c 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-11-21 +date: 2023-11-27 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 019d14688808..2eda51c59225 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-11-21 +date: 2023-11-27 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 166f3ed0b0b1..fac320c7b71c 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-11-21 +date: 2023-11-27 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 6530d67e74df..82d7132fed95 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_field_utils.mdx b/api_docs/kbn_field_utils.mdx index 94632df85bc8..c2421793b2a6 100644 --- a/api_docs/kbn_field_utils.mdx +++ b/api_docs/kbn_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-utils title: "@kbn/field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-utils plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-utils'] --- import kbnFieldUtilsObj from './kbn_field_utils.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index a0e32b994646..d5ae17d72509 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-11-21 +date: 2023-11-27 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 75f8fe4cf2b7..297c6ac6bb25 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-11-21 +date: 2023-11-27 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 001b92ac1b31..12e59f2064f1 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-11-21 +date: 2023-11-27 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 a128e75d2bc3..aa5f51b7fb0a 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-11-21 +date: 2023-11-27 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 7a478239e998..96bd944fb69a 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index a795592fc5d1..06509631e441 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-11-21 +date: 2023-11-27 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 cf41bad68261..e6a86fa5c254 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-11-21 +date: 2023-11-27 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 16796582f8a7..4e01acd9a95d 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-11-21 +date: 2023-11-27 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 aacda0ded28a..46aa657fac06 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-11-21 +date: 2023-11-27 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 9a85a0f5cf51..1c74f6d53e84 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-11-21 +date: 2023-11-27 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 94f5421a77cd..fcd6b3b18a73 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-11-21 +date: 2023-11-27 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 c5f3b626d6c4..819f4bba6dbe 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-11-21 +date: 2023-11-27 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 855686c7e751..1dda9b2b0a83 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-11-21 +date: 2023-11-27 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 6b2df4490bea..19276e94655b 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-11-21 +date: 2023-11-27 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 71a9a3c9628c..27d490faa585 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-11-21 +date: 2023-11-27 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 81cbf3de7a0b..428b5d23dee0 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-11-21 +date: 2023-11-27 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 baa2b7c59236..6a89ab405985 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-11-21 +date: 2023-11-27 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 7134a6b5111b..410884860612 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-11-21 +date: 2023-11-27 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 4516c2a6fbce..276651e60883 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-11-21 +date: 2023-11-27 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 f7fc8909007f..e63b7699ad4a 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-11-21 +date: 2023-11-27 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 920d818e7209..0bd509185808 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-11-21 +date: 2023-11-27 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 839aaebe1878..b4a9664930e4 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-11-21 +date: 2023-11-27 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 25bf0d639148..7e028cebce8e 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-11-21 +date: 2023-11-27 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 3843787a91b2..56c9f7743930 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-11-21 +date: 2023-11-27 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 1c4747f8f512..1540af7c267c 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-11-21 +date: 2023-11-27 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 cc618d840081..955f3809c421 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-11-21 +date: 2023-11-27 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 e3f1292bdaf7..5bae8706f2ef 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_settings_application.mdx b/api_docs/kbn_management_settings_application.mdx index c89f2595278c..1808200e40e6 100644 --- a/api_docs/kbn_management_settings_application.mdx +++ b/api_docs/kbn_management_settings_application.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-application title: "@kbn/management-settings-application" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-application plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-application'] --- import kbnManagementSettingsApplicationObj from './kbn_management_settings_application.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_category.mdx b/api_docs/kbn_management_settings_components_field_category.mdx index a77ff49637cd..3c4f8160fe48 100644 --- a/api_docs/kbn_management_settings_components_field_category.mdx +++ b/api_docs/kbn_management_settings_components_field_category.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-field-category title: "@kbn/management-settings-components-field-category" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-field-category plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-category'] --- import kbnManagementSettingsComponentsFieldCategoryObj from './kbn_management_settings_components_field_category.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_field_input.mdx b/api_docs/kbn_management_settings_components_field_input.mdx index 93c1faa74c0a..f90aef74612b 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-11-21 +date: 2023-11-27 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 d2c50166a0b2..6bdedab4443b 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-field-row'] --- import kbnManagementSettingsComponentsFieldRowObj from './kbn_management_settings_components_field_row.devdocs.json'; diff --git a/api_docs/kbn_management_settings_components_form.mdx b/api_docs/kbn_management_settings_components_form.mdx index a4a182216dd2..7ec32e001fa2 100644 --- a/api_docs/kbn_management_settings_components_form.mdx +++ b/api_docs/kbn_management_settings_components_form.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-settings-components-form title: "@kbn/management-settings-components-form" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-settings-components-form plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-settings-components-form'] --- import kbnManagementSettingsComponentsFormObj from './kbn_management_settings_components_form.devdocs.json'; diff --git a/api_docs/kbn_management_settings_field_definition.mdx b/api_docs/kbn_management_settings_field_definition.mdx index 477bd6ec4480..f4ce8f12492b 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-11-21 +date: 2023-11-27 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 ddec605878f9..0838caf95bc2 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-11-21 +date: 2023-11-27 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 5f198ea5cdc0..6f046fe84760 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-11-21 +date: 2023-11-27 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 5a4e3b875f24..3b1b56c99458 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-11-21 +date: 2023-11-27 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 b4655ad105d3..381815a2c969 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-11-21 +date: 2023-11-27 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 99d70b50b494..43b4829ddc1f 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-11-21 +date: 2023-11-27 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 d9461dc0769c..6cfe10fa2c49 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-11-21 +date: 2023-11-27 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 5b6c9864c447..4d0206640251 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-11-21 +date: 2023-11-27 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 66af525b30c8..e11c9596a311 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-11-21 +date: 2023-11-27 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 87766229e87e..d9d648565f15 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-11-21 +date: 2023-11-27 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 5b2662c1db45..ffe06966b7ea 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_chi2test.mdx b/api_docs/kbn_ml_chi2test.mdx index 171e8d674af9..12e8602225c8 100644 --- a/api_docs/kbn_ml_chi2test.mdx +++ b/api_docs/kbn_ml_chi2test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-chi2test title: "@kbn/ml-chi2test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-chi2test plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-chi2test'] --- import kbnMlChi2testObj from './kbn_ml_chi2test.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index a34d9281ce7a..95c46eb783e5 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_ml_data_grid.devdocs.json index 0e63c9f639c1..14fcad6d9b0a 100644 --- a/api_docs/kbn_ml_data_grid.devdocs.json +++ b/api_docs/kbn_ml_data_grid.devdocs.json @@ -347,10 +347,10 @@ }, { "parentPluginId": "@kbn/ml-data-grid", - "id": "def-common.getFieldsFromKibanaIndexPattern", + "id": "def-common.getFieldsFromKibanaDataView", "type": "Function", "tags": [], - "label": "getFieldsFromKibanaIndexPattern", + "label": "getFieldsFromKibanaDataView", "description": [ "\nRetrieves fields from a Kibana data view." ], @@ -371,7 +371,7 @@ "children": [ { "parentPluginId": "@kbn/ml-data-grid", - "id": "def-common.getFieldsFromKibanaIndexPattern.$1", + "id": "def-common.getFieldsFromKibanaDataView.$1", "type": "Object", "tags": [], "label": "dataView", @@ -2489,12 +2489,12 @@ }, { "parentPluginId": "@kbn/ml-data-grid", - "id": "def-common.UseIndexDataReturnType.indexPatternFields", + "id": "def-common.UseIndexDataReturnType.dataViewFields", "type": "Array", "tags": [], - "label": "indexPatternFields", + "label": "dataViewFields", "description": [ - "\nOptional index pattern fields." + "\nOptional data view fields." ], "signature": [ "string[] | undefined" diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 034a469710ce..7d6067a8f941 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-11-21 +date: 2023-11-27 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 a109a459e6eb..c1c9baaae3ff 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-11-21 +date: 2023-11-27 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 b77d4ec65586..de6be91f086d 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-11-21 +date: 2023-11-27 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 a5b4715dfc9a..6c87f5e17018 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-11-21 +date: 2023-11-27 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 489901c47b99..036e048089e8 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-11-21 +date: 2023-11-27 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 fb06e1275927..bdc92fce9b5b 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-11-21 +date: 2023-11-27 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 0c038656400e..cd62733f7e93 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-11-21 +date: 2023-11-27 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 216fbeb7d948..ffa8819d1fec 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-11-21 +date: 2023-11-27 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 f01a54d57554..0cc81a085e2d 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-11-21 +date: 2023-11-27 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 0f8736f232a4..7790343fc0b7 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-11-21 +date: 2023-11-27 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 e56bbc95d1a7..0c5bd2328233 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-11-21 +date: 2023-11-27 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 9709c86c6b4d..0d58307edcf1 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-11-21 +date: 2023-11-27 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 7df33cf629bc..50239b86d0e5 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-11-21 +date: 2023-11-27 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 c4be68e7cb07..fe45c9a23306 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-11-21 +date: 2023-11-27 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 f25c7a6feeee..a40ab5968398 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-11-21 +date: 2023-11-27 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 ed89de867e98..02b1cc6d6635 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-11-21 +date: 2023-11-27 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 46ce7fb3d70f..e93125b1e697 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_ui_actions.devdocs.json b/api_docs/kbn_ml_ui_actions.devdocs.json new file mode 100644 index 000000000000..6fe15ef82553 --- /dev/null +++ b/api_docs/kbn_ml_ui_actions.devdocs.json @@ -0,0 +1,298 @@ +{ + "id": "@kbn/ml-ui-actions", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CategorizeFieldContext", + "type": "Interface", + "tags": [], + "label": "CategorizeFieldContext", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CategorizeFieldContext.field", + "type": "Object", + "tags": [], + "label": "field", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + } + ], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CategorizeFieldContext.dataView", + "type": "Object", + "tags": [], + "label": "dataView", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + } + ], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CategorizeFieldContext.originatingApp", + "type": "string", + "tags": [], + "label": "originatingApp", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CategorizeFieldContext.additionalFilter", + "type": "Object", + "tags": [], + "label": "additionalFilter", + "description": [], + "signature": [ + "{ from: number; to: number; field?: { name: string; value: string; } | undefined; } | undefined" + ], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CreateCategorizationADJobContext", + "type": "Interface", + "tags": [], + "label": "CreateCategorizationADJobContext", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CreateCategorizationADJobContext.field", + "type": "Object", + "tags": [], + "label": "field", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataViewField", + "text": "DataViewField" + } + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CreateCategorizationADJobContext.dataView", + "type": "Object", + "tags": [], + "label": "dataView", + "description": [], + "signature": [ + { + "pluginId": "dataViews", + "scope": "common", + "docId": "kibDataViewsPluginApi", + "section": "def-common.DataView", + "text": "DataView" + } + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CreateCategorizationADJobContext.query", + "type": "Object", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "QueryDslQueryContainer" + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CreateCategorizationADJobContext.timeRange", + "type": "Object", + "tags": [], + "label": "timeRange", + "description": [], + "signature": [ + "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.ACTION_CATEGORIZE_FIELD", + "type": "string", + "tags": [], + "label": "ACTION_CATEGORIZE_FIELD", + "description": [], + "signature": [ + "\"ACTION_CATEGORIZE_FIELD\"" + ], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CATEGORIZE_FIELD_TRIGGER", + "type": "string", + "tags": [], + "label": "CATEGORIZE_FIELD_TRIGGER", + "description": [], + "signature": [ + "\"CATEGORIZE_FIELD_TRIGGER\"" + ], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION", + "type": "string", + "tags": [], + "label": "CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION", + "description": [], + "signature": [ + "\"createMLADCategorizationJobAction\"" + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER", + "type": "string", + "tags": [], + "label": "CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER", + "description": [], + "signature": [ + "\"CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER\"" + ], + "path": "x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.categorizeFieldTrigger", + "type": "Object", + "tags": [], + "label": "categorizeFieldTrigger", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.categorizeFieldTrigger.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.categorizeFieldTrigger.title", + "type": "string", + "tags": [], + "label": "title", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/ml-ui-actions", + "id": "def-common.categorizeFieldTrigger.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ml_ui_actions.mdx b/api_docs/kbn_ml_ui_actions.mdx new file mode 100644 index 000000000000..f7dfefcbd699 --- /dev/null +++ b/api_docs/kbn_ml_ui_actions.mdx @@ -0,0 +1,36 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibKbnMlUiActionsPluginApi +slug: /kibana-dev-docs/api/kbn-ml-ui-actions +title: "@kbn/ml-ui-actions" +image: https://source.unsplash.com/400x175/?github +description: API docs for the @kbn/ml-ui-actions plugin +date: 2023-11-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-ui-actions'] +--- +import kbnMlUiActionsObj from './kbn_ml_ui_actions.devdocs.json'; + + + +Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 18 | 0 | 18 | 0 | + +## Common + +### Objects + + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 5bccc23c234f..5f7c12e70e4c 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-11-21 +date: 2023-11-27 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 583c7100a45f..3320e5bce9ab 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-11-21 +date: 2023-11-27 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 112b328fe214..079e6d3c2d18 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-11-21 +date: 2023-11-27 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 34e4428fac02..fc0c109e8428 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.devdocs.json b/api_docs/kbn_observability_alerting_test_data.devdocs.json index 96da803aa4b6..d75f51f28846 100644 --- a/api_docs/kbn_observability_alerting_test_data.devdocs.json +++ b/api_docs/kbn_observability_alerting_test_data.devdocs.json @@ -434,7 +434,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; filter: string; aggType: ", "Aggregators", @@ -597,7 +597,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; filter: string; aggType: ", "Aggregators", @@ -774,7 +774,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; filter: string; aggType: ", "Aggregators", @@ -937,7 +937,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; field: string; aggType: ", "Aggregators", @@ -1100,7 +1100,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; field: string; aggType: ", "Aggregators", @@ -1277,7 +1277,7 @@ "label": "criteria", "description": [], "signature": [ - "{ aggType: string; comparator: ", + "{ comparator: ", "Comparator", "; threshold: number[]; timeSize: number; timeUnit: string; metrics: { name: string; field: string; aggType: ", "Aggregators", diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 71d1e7bd002b..dccd37bd409d 100644 --- a/api_docs/kbn_observability_alerting_test_data.mdx +++ b/api_docs/kbn_observability_alerting_test_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alerting-test-data title: "@kbn/observability-alerting-test-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alerting-test-data plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alerting-test-data'] --- import kbnObservabilityAlertingTestDataObj from './kbn_observability_alerting_test_data.devdocs.json'; diff --git a/api_docs/kbn_openapi_generator.mdx b/api_docs/kbn_openapi_generator.mdx index 8e71595b35ad..fd64ac097223 100644 --- a/api_docs/kbn_openapi_generator.mdx +++ b/api_docs/kbn_openapi_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-openapi-generator title: "@kbn/openapi-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/openapi-generator plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/openapi-generator'] --- import kbnOpenapiGeneratorObj from './kbn_openapi_generator.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 9b0aadadedec..866016a5d2de 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-11-21 +date: 2023-11-27 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 10273abb264f..f55a35b3110e 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-11-21 +date: 2023-11-27 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 5bc660b19cc3..621e573cdd71 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-11-21 +date: 2023-11-27 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 a43e7de1ab37..a1ff7f8ad796 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-11-21 +date: 2023-11-27 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 28ad7e5eb155..5a53b9b96eaa 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-11-21 +date: 2023-11-27 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 2daa6c51a19c..fd161af3c372 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.devdocs.json b/api_docs/kbn_profiling_utils.devdocs.json index 597124dd7517..f49a43e57c1f 100644 --- a/api_docs/kbn_profiling_utils.devdocs.json +++ b/api_docs/kbn_profiling_utils.devdocs.json @@ -2699,6 +2699,18 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/profiling-utils", + "id": "def-common.TopNComparisonFunctionSortField", + "type": "Enum", + "tags": [], + "label": "TopNComparisonFunctionSortField", + "description": [], + "path": "packages/kbn-profiling-utils/common/functions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/profiling-utils", "id": "def-common.TopNFunctionSortField", @@ -2990,6 +3002,82 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/profiling-utils", + "id": "def-common.topNComparisonFunctionSortFieldRt", + "type": "Object", + "tags": [], + "label": "topNComparisonFunctionSortFieldRt", + "description": [], + "signature": [ + "UnionC", + "<[", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonRank>, ", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonFrame>, ", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonSamples>, ", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonSelfCPU>, ", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonTotalCPU>, ", + "LiteralC", + "<", + { + "pluginId": "@kbn/profiling-utils", + "scope": "common", + "docId": "kibKbnProfilingUtilsPluginApi", + "section": "def-common.TopNComparisonFunctionSortField", + "text": "TopNComparisonFunctionSortField" + }, + ".ComparisonDiff>]>" + ], + "path": "packages/kbn-profiling-utils/common/functions.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/profiling-utils", "id": "def-common.topNFunctionSortFieldRt", diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index dc85eb5abc3a..8d6a4d686d1e 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/profiling-utils'] --- import kbnProfilingUtilsObj from './kbn_profiling_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 171 | 0 | 28 | 0 | +| 173 | 0 | 30 | 0 | ## Common diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index afa6ab1eb712..d3bb1f8c33cf 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-11-21 +date: 2023-11-27 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 0ad9f12676fe..399d81627081 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-11-21 +date: 2023-11-27 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 e8723b1caa78..c3349c4759a8 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-11-21 +date: 2023-11-27 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 cb89b8b76c61..756d2d716a14 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-11-21 +date: 2023-11-27 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 21e251bbfff3..a2a5eb471a01 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-11-21 +date: 2023-11-27 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 6dc5aa790f3b..778c2f167fb6 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-11-21 +date: 2023-11-27 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 89d12c222a30..23383f3cfc40 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-11-21 +date: 2023-11-27 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 476500b25aba..b5813906f33c 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-11-21 +date: 2023-11-27 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 96615412bf98..0b319a6845e8 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-11-21 +date: 2023-11-27 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 e27847ef6a5b..161ab5873592 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-11-21 +date: 2023-11-27 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 6386639f48cc..d747f9fe4459 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-11-21 +date: 2023-11-27 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 494b1d70e6f4..7f5e25d409a5 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-11-21 +date: 2023-11-27 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 bd31938fc50b..51f9689c5687 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 4ec8465eb1a7..84c0040b2656 100644 --- a/api_docs/kbn_reporting_export_types_csv.mdx +++ b/api_docs/kbn_reporting_export_types_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv title: "@kbn/reporting-export-types-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv'] --- import kbnReportingExportTypesCsvObj from './kbn_reporting_export_types_csv.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv_common.mdx b/api_docs/kbn_reporting_export_types_csv_common.mdx index 13af8078f5af..84b93ef64aea 100644 --- a/api_docs/kbn_reporting_export_types_csv_common.mdx +++ b/api_docs/kbn_reporting_export_types_csv_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-csv-common title: "@kbn/reporting-export-types-csv-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-csv-common plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-csv-common'] --- import kbnReportingExportTypesCsvCommonObj from './kbn_reporting_export_types_csv_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf.mdx b/api_docs/kbn_reporting_export_types_pdf.mdx index 8c0c8851048c..ed853f5c227a 100644 --- a/api_docs/kbn_reporting_export_types_pdf.mdx +++ b/api_docs/kbn_reporting_export_types_pdf.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf title: "@kbn/reporting-export-types-pdf" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf'] --- import kbnReportingExportTypesPdfObj from './kbn_reporting_export_types_pdf.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_pdf_common.mdx b/api_docs/kbn_reporting_export_types_pdf_common.mdx index 5e8aedd41972..aa1cec42ce3b 100644 --- a/api_docs/kbn_reporting_export_types_pdf_common.mdx +++ b/api_docs/kbn_reporting_export_types_pdf_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-pdf-common title: "@kbn/reporting-export-types-pdf-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-pdf-common plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-pdf-common'] --- import kbnReportingExportTypesPdfCommonObj from './kbn_reporting_export_types_pdf_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png.mdx b/api_docs/kbn_reporting_export_types_png.mdx index ab823856b9e5..3764476edbbc 100644 --- a/api_docs/kbn_reporting_export_types_png.mdx +++ b/api_docs/kbn_reporting_export_types_png.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png title: "@kbn/reporting-export-types-png" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png'] --- import kbnReportingExportTypesPngObj from './kbn_reporting_export_types_png.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_png_common.mdx b/api_docs/kbn_reporting_export_types_png_common.mdx index 1e47c43bd02c..552efdf99bdf 100644 --- a/api_docs/kbn_reporting_export_types_png_common.mdx +++ b/api_docs/kbn_reporting_export_types_png_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-export-types-png-common title: "@kbn/reporting-export-types-png-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-export-types-png-common plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-export-types-png-common'] --- import kbnReportingExportTypesPngCommonObj from './kbn_reporting_export_types_png_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_mocks_server.mdx b/api_docs/kbn_reporting_mocks_server.mdx index 7efa8bd0e379..2262bbb5d47e 100644 --- a/api_docs/kbn_reporting_mocks_server.mdx +++ b/api_docs/kbn_reporting_mocks_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-mocks-server title: "@kbn/reporting-mocks-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-mocks-server plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-mocks-server'] --- import kbnReportingMocksServerObj from './kbn_reporting_mocks_server.devdocs.json'; diff --git a/api_docs/kbn_reporting_public.mdx b/api_docs/kbn_reporting_public.mdx index cc5685246d8c..dd3085f02483 100644 --- a/api_docs/kbn_reporting_public.mdx +++ b/api_docs/kbn_reporting_public.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-public title: "@kbn/reporting-public" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-public plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-public'] --- import kbnReportingPublicObj from './kbn_reporting_public.devdocs.json'; diff --git a/api_docs/kbn_reporting_server.mdx b/api_docs/kbn_reporting_server.mdx index 53127310cf99..ef55ec4a395c 100644 --- a/api_docs/kbn_reporting_server.mdx +++ b/api_docs/kbn_reporting_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-server title: "@kbn/reporting-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-server plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-server'] --- import kbnReportingServerObj from './kbn_reporting_server.devdocs.json'; diff --git a/api_docs/kbn_resizable_layout.mdx b/api_docs/kbn_resizable_layout.mdx index 7f4c0213c2c3..c8152e5f28a4 100644 --- a/api_docs/kbn_resizable_layout.mdx +++ b/api_docs/kbn_resizable_layout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-resizable-layout title: "@kbn/resizable-layout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/resizable-layout plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index 7e6fea8f1c18..3ac9b9eac437 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-11-21 +date: 2023-11-27 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 4c5ad7bc8637..56dcc47067b9 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-11-21 +date: 2023-11-27 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 468c67967ce8..3ef5d9072f7a 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-11-21 +date: 2023-11-27 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 930579816d65..dca8f6ae501e 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_search_api_panels.devdocs.json index 8558d593d429..5c01dba78684 100644 --- a/api_docs/kbn_search_api_panels.devdocs.json +++ b/api_docs/kbn_search_api_panels.devdocs.json @@ -279,7 +279,7 @@ "label": "IngestData", "description": [], "signature": [ - "({ codeSnippet, selectedLanguage, setSelectedLanguage, docLinks, assetBasePath, application, sharePlugin, languages, consoleRequest, }: React.PropsWithChildren) => JSX.Element" + "({ codeSnippet, selectedLanguage, setSelectedLanguage, docLinks, assetBasePath, application, sharePlugin, languages, consoleRequest, additionalIngestionPanel, }: React.PropsWithChildren) => JSX.Element" ], "path": "packages/kbn-search-api-panels/components/ingest_data.tsx", "deprecated": false, @@ -290,7 +290,7 @@ "id": "def-common.IngestData.$1", "type": "CompoundType", "tags": [], - "label": "{\n codeSnippet,\n selectedLanguage,\n setSelectedLanguage,\n docLinks,\n assetBasePath,\n application,\n sharePlugin,\n languages,\n consoleRequest,\n}", + "label": "{\n codeSnippet,\n selectedLanguage,\n setSelectedLanguage,\n docLinks,\n assetBasePath,\n application,\n sharePlugin,\n languages,\n consoleRequest,\n additionalIngestionPanel,\n}", "description": [], "signature": [ "React.PropsWithChildren" @@ -306,29 +306,29 @@ }, { "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.InstallClientPanel", + "id": "def-common.IngestionsPanel", "type": "Function", "tags": [], - "label": "InstallClientPanel", + "label": "IngestionsPanel", "description": [], "signature": [ - "({ codeSnippet, consoleRequest, language, languages, setSelectedLanguage, assetBasePath, application, sharePlugin, isPanelLeft, overviewPanelProps, }: React.PropsWithChildren) => JSX.Element" + "({ additionalIngestionPanel, docLinks, assetBasePath, }: React.PropsWithChildren) => JSX.Element" ], - "path": "packages/kbn-search-api-panels/components/install_client.tsx", + "path": "packages/kbn-search-api-panels/components/ingestions_panel.tsx", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.InstallClientPanel.$1", + "id": "def-common.IngestionsPanel.$1", "type": "CompoundType", "tags": [], - "label": "{\n codeSnippet,\n consoleRequest,\n language,\n languages,\n setSelectedLanguage,\n assetBasePath,\n application,\n sharePlugin,\n isPanelLeft = true,\n overviewPanelProps,\n}", + "label": "{\n additionalIngestionPanel,\n docLinks,\n assetBasePath,\n}", "description": [], "signature": [ - "React.PropsWithChildren" + "React.PropsWithChildren" ], - "path": "packages/kbn-search-api-panels/components/install_client.tsx", + "path": "packages/kbn-search-api-panels/components/ingestions_panel.tsx", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -339,45 +339,29 @@ }, { "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.IntegrationsPanel", + "id": "def-common.InstallClientPanel", "type": "Function", "tags": [], - "label": "IntegrationsPanel", + "label": "InstallClientPanel", "description": [], "signature": [ - "({ docLinks, assetBasePath, }: React.PropsWithChildren<", - { - "pluginId": "@kbn/search-api-panels", - "scope": "common", - "docId": "kibKbnSearchApiPanelsPluginApi", - "section": "def-common.IntegrationsPanelProps", - "text": "IntegrationsPanelProps" - }, - ">) => JSX.Element" + "({ codeSnippet, consoleRequest, language, languages, setSelectedLanguage, assetBasePath, application, sharePlugin, isPanelLeft, overviewPanelProps, }: React.PropsWithChildren) => JSX.Element" ], - "path": "packages/kbn-search-api-panels/components/integrations_panel.tsx", + "path": "packages/kbn-search-api-panels/components/install_client.tsx", "deprecated": false, "trackAdoption": false, "children": [ { "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.IntegrationsPanel.$1", + "id": "def-common.InstallClientPanel.$1", "type": "CompoundType", "tags": [], - "label": "{\n docLinks,\n assetBasePath,\n}", + "label": "{\n codeSnippet,\n consoleRequest,\n language,\n languages,\n setSelectedLanguage,\n assetBasePath,\n application,\n sharePlugin,\n isPanelLeft = true,\n overviewPanelProps,\n}", "description": [], "signature": [ - "React.PropsWithChildren<", - { - "pluginId": "@kbn/search-api-panels", - "scope": "common", - "docId": "kibKbnSearchApiPanelsPluginApi", - "section": "def-common.IntegrationsPanelProps", - "text": "IntegrationsPanelProps" - }, - ">" + "React.PropsWithChildren" ], - "path": "packages/kbn-search-api-panels/components/integrations_panel.tsx", + "path": "packages/kbn-search-api-panels/components/install_client.tsx", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -599,45 +583,6 @@ } ], "interfaces": [ - { - "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.IntegrationsPanelProps", - "type": "Interface", - "tags": [], - "label": "IntegrationsPanelProps", - "description": [], - "path": "packages/kbn-search-api-panels/components/integrations_panel.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.IntegrationsPanelProps.docLinks", - "type": "Object", - "tags": [], - "label": "docLinks", - "description": [], - "signature": [ - "{ beats: string; connectors: string; logstash: string; }" - ], - "path": "packages/kbn-search-api-panels/components/integrations_panel.tsx", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/search-api-panels", - "id": "def-common.IntegrationsPanelProps.assetBasePath", - "type": "string", - "tags": [], - "label": "assetBasePath", - "description": [], - "path": "packages/kbn-search-api-panels/components/integrations_panel.tsx", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/search-api-panels", "id": "def-common.LanguageDefinition", diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 985b62362071..f6fd1b0ac962 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-api-panels'] --- import kbnSearchApiPanelsObj from './kbn_search_api_panels.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/te | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 69 | 0 | 69 | 0 | +| 66 | 0 | 66 | 0 | ## Common diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 24f1c1909efc..7c984b960694 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-11-21 +date: 2023-11-27 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 f87a2cb615af..2b7077a7831e 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-11-21 +date: 2023-11-27 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 44bcf2e3c721..507953da04d2 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-11-21 +date: 2023-11-27 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 ad8a5390022e..1da33f2f7e41 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-11-21 +date: 2023-11-27 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 dcd439b72855..7a3f1ad96985 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-11-21 +date: 2023-11-27 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 1c90ef6ef1f5..edc3b5501f73 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-11-21 +date: 2023-11-27 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 9da8887a096d..55f72249e078 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_securitysolution_data_table.devdocs.json index 7bdb8cf37086..b003dd04c9e8 100644 --- a/api_docs/kbn_securitysolution_data_table.devdocs.json +++ b/api_docs/kbn_securitysolution_data_table.devdocs.json @@ -1864,6 +1864,14 @@ "section": "def-common.TableEntityType", "text": "TableEntityType" }, + "; \"risk-inputs\": ", + { + "pluginId": "@kbn/securitysolution-data-table", + "scope": "common", + "docId": "kibKbnSecuritysolutionDataTablePluginApi", + "section": "def-common.TableEntityType", + "text": "TableEntityType" + }, "; }" ], "path": "x-pack/packages/security-solution/data_table/common/types/data_table/index.ts", diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index e7ea75549ee4..752f157daab3 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-11-21 +date: 2023-11-27 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 9b2b7c58cde2..f5557c02a3b5 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-11-21 +date: 2023-11-27 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 afb4c599cbd3..0f1e833b1d9f 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-11-21 +date: 2023-11-27 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 0ddc8aa14343..5443c6add842 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-11-21 +date: 2023-11-27 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 8550f363fe22..7d4beeb6b0eb 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-11-21 +date: 2023-11-27 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 4da7a082bf9c..b51b472147d2 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-11-21 +date: 2023-11-27 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 d454a89e70d8..65ddef0b0eb7 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-11-21 +date: 2023-11-27 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 ceef74614e7f..e62d2db1e425 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-11-21 +date: 2023-11-27 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 01a9adc1acf5..7c9418a80b6d 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-11-21 +date: 2023-11-27 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 f0981d3a9212..97780286c372 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-11-21 +date: 2023-11-27 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 36f572d4bc47..62a9b52611be 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-11-21 +date: 2023-11-27 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 00049806daf0..49515d75e36f 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-11-21 +date: 2023-11-27 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 9e714b185235..2a9a06d05fa7 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-11-21 +date: 2023-11-27 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 1d89917256ea..a5ad21eb596f 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-11-21 +date: 2023-11-27 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 c2649d95a964..ea798c7a6e48 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-11-21 +date: 2023-11-27 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 a9333f01a830..83e71ee4c643 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-11-21 +date: 2023-11-27 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 315665ac9054..615ecb46009c 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_server_http_tools.devdocs.json index ace0c332ca51..768f9868081a 100644 --- a/api_docs/kbn_server_http_tools.devdocs.json +++ b/api_docs/kbn_server_http_tools.devdocs.json @@ -177,6 +177,52 @@ "trackAdoption": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.SslConfig.isEqualTo", + "type": "Function", + "tags": [], + "label": "isEqualTo", + "description": [], + "signature": [ + "(otherConfig: ", + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.SslConfig", + "text": "SslConfig" + }, + ") => boolean" + ], + "path": "packages/kbn-server-http-tools/src/ssl/ssl_config.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.SslConfig.isEqualTo.$1", + "type": "Object", + "tags": [], + "label": "otherConfig", + "description": [], + "signature": [ + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.SslConfig", + "text": "SslConfig" + } + ], + "path": "packages/kbn-server-http-tools/src/ssl/ssl_config.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -492,6 +538,125 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.getServerTLSOptions", + "type": "Function", + "tags": [], + "label": "getServerTLSOptions", + "description": [ + "\nConverts Kibana `SslConfig` into `TLSOptions` that are accepted by the Hapi server,\nand by https.Server.setSecureContext()" + ], + "signature": [ + "(ssl: ", + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.ISslConfig", + "text": "ISslConfig" + }, + ") => ", + "ServerOptions", + " | undefined" + ], + "path": "packages/kbn-server-http-tools/src/get_server_options.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.getServerTLSOptions.$1", + "type": "Object", + "tags": [], + "label": "ssl", + "description": [], + "signature": [ + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.ISslConfig", + "text": "ISslConfig" + } + ], + "path": "packages/kbn-server-http-tools/src/get_server_options.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.setTlsConfig", + "type": "Function", + "tags": [], + "label": "setTlsConfig", + "description": [], + "signature": [ + "(hapiServer: ", + "Server", + ", sslConfig: ", + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.ISslConfig", + "text": "ISslConfig" + }, + ") => void" + ], + "path": "packages/kbn-server-http-tools/src/set_tls_config.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.setTlsConfig.$1", + "type": "Object", + "tags": [], + "label": "hapiServer", + "description": [], + "signature": [ + "Server" + ], + "path": "packages/kbn-server-http-tools/src/set_tls_config.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/server-http-tools", + "id": "def-common.setTlsConfig.$2", + "type": "Object", + "tags": [], + "label": "sslConfig", + "description": [], + "signature": [ + { + "pluginId": "@kbn/server-http-tools", + "scope": "common", + "docId": "kibKbnServerHttpToolsPluginApi", + "section": "def-common.ISslConfig", + "text": "ISslConfig" + } + ], + "path": "packages/kbn-server-http-tools/src/set_tls_config.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 8ebf8129ead4..9e54f0a494c7 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 54 | 0 | 51 | 1 | +| 61 | 0 | 57 | 1 | ## Common diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index 572897df0e4c..6495770b5f16 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-11-21 +date: 2023-11-27 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 b4993205dc03..627aeed7e797 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-11-21 +date: 2023-11-27 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 d83199ba1a4d..08d8224681a2 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-11-21 +date: 2023-11-27 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 cf0f23471f86..1556f824669a 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-11-21 +date: 2023-11-27 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 78d35f9df969..ad4168309983 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-11-21 +date: 2023-11-27 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 4c28b9678519..5f3395813b4f 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-11-21 +date: 2023-11-27 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 ccc464bbb29c..518c647b1608 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-11-21 +date: 2023-11-27 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 f39e950bb881..1a59cec3df39 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-11-21 +date: 2023-11-27 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 044babbc061f..2071c397d341 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index e1c0809aaa7d..67efa360022a 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index 44e04bb592dd..a2b252afffa5 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-11-21 +date: 2023-11-27 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 f5a7ce28fcf1..b24a811e7a2d 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-11-21 +date: 2023-11-27 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 5b28cc95d6e2..2474dfd520df 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-11-21 +date: 2023-11-27 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 5d07ffe90bcf..a3f7c71536e5 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_error_boundary.mdx b/api_docs/kbn_shared_ux_error_boundary.mdx index 9cb4bb95c3ee..aa3e4be20aa1 100644 --- a/api_docs/kbn_shared_ux_error_boundary.mdx +++ b/api_docs/kbn_shared_ux_error_boundary.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-error-boundary title: "@kbn/shared-ux-error-boundary" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-error-boundary plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-error-boundary'] --- import kbnSharedUxErrorBoundaryObj from './kbn_shared_ux_error_boundary.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 48cde294cc59..6427403f67ca 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-11-21 +date: 2023-11-27 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 5ebbe3a3a2e4..ae22ff568ed1 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-11-21 +date: 2023-11-27 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 ebf709b516c0..5156a3fb18c4 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-11-21 +date: 2023-11-27 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 f4d07e35c15b..cbb3ec18e81c 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-11-21 +date: 2023-11-27 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 4f5c6b375d50..14ef7677eda3 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-11-21 +date: 2023-11-27 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 482d2c34d828..d5fc7d2f4bac 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-11-21 +date: 2023-11-27 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 1bb6f2fe5a02..2b49d1343f11 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-11-21 +date: 2023-11-27 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 c5d4aa744aff..dcff7c006c53 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_shared_ux_link_redirect_app.devdocs.json index ae8568c37433..aa7633649473 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.devdocs.json +++ b/api_docs/kbn_shared_ux_link_redirect_app.devdocs.json @@ -29,7 +29,9 @@ "\nA service-enabled component that provides Kibana-specific functionality to the `RedirectAppLinks`\npure component.\n" ], "signature": [ - "({ children }: { children?: React.ReactNode; }) => JSX.Element" + "({ children, ...props }: React.PropsWithChildren>) => JSX.Element" ], "path": "packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx", "deprecated": false, @@ -38,12 +40,14 @@ { "parentPluginId": "@kbn/shared-ux-link-redirect-app", "id": "def-common.RedirectAppLinks.$1", - "type": "Object", + "type": "CompoundType", "tags": [], - "label": "{ children }", + "label": "{\n children,\n ...props\n}", "description": [], "signature": [ - "{ children?: React.ReactNode; }" + "React.PropsWithChildren>" ], "path": "packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx", "deprecated": false, @@ -64,7 +68,7 @@ "\nUtility component that will intercept click events on children anchor (``) elements to call\n`navigateToUrl` with the link's href. This will trigger SPA friendly navigation when the link points\nto a valid Kibana app.\n" ], "signature": [ - "({ children, navigateToUrl, currentAppId, }: React.PropsWithChildren<", + "({ children, navigateToUrl, currentAppId, ...containerProps }: React.PropsWithChildren<", "RedirectAppLinksComponentProps", ">) => JSX.Element" ], @@ -77,7 +81,7 @@ "id": "def-common.RedirectAppLinks.$1", "type": "CompoundType", "tags": [], - "label": "{\n children,\n navigateToUrl,\n currentAppId,\n}", + "label": "{\n children,\n navigateToUrl,\n currentAppId,\n ...containerProps\n}", "description": [], "signature": [ "React.PropsWithChildren<", @@ -317,9 +321,11 @@ "Props for the `RedirectAppLinks` component." ], "signature": [ + "(", "RedirectAppLinksKibanaDependencies", " | ", - "RedirectAppLinksServices" + "RedirectAppLinksServices", + ") & React.ClassAttributes & React.HTMLAttributes" ], "path": "packages/shared-ux/link/redirect_app/types/index.d.ts", "deprecated": false, diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 33898faff645..4f936dfedb21 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-11-21 +date: 2023-11-27 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 b3929fd1d94a..87ea1867d73e 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-11-21 +date: 2023-11-27 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 8c6c28af8793..dcd183b06548 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-11-21 +date: 2023-11-27 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 dae4a7a431af..f535d02e139c 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-11-21 +date: 2023-11-27 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 69f1a53e9977..a87bd9f1d586 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-11-21 +date: 2023-11-27 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 9565f422810d..51dd2bff0c77 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-11-21 +date: 2023-11-27 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 2612e20256c1..68aa2f1d9d20 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-11-21 +date: 2023-11-27 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 01c42b69b095..eca4e7ae0e40 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-11-21 +date: 2023-11-27 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 6286732801e1..d7be625f17fa 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-11-21 +date: 2023-11-27 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 e90b7cb6e700..d8e11d74a660 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-11-21 +date: 2023-11-27 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 7a6ea0b4710a..29af46a5457c 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-11-21 +date: 2023-11-27 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 fac085487858..70a715bc84c5 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-11-21 +date: 2023-11-27 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 c5ee65582d26..fe00d62d6651 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-11-21 +date: 2023-11-27 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 28e34a5504d2..bbb8b930152a 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-11-21 +date: 2023-11-27 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 38fe94ee77ae..d7491f8fb060 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-11-21 +date: 2023-11-27 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 ebf52258593c..070f55c61b0f 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-11-21 +date: 2023-11-27 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 af53fa0f9cb1..0528f8d96557 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-11-21 +date: 2023-11-27 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 f88cf7ca6300..00d9eddda204 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-11-21 +date: 2023-11-27 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 9bbb77007d7e..32cf5281f9a3 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-11-21 +date: 2023-11-27 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 432e103cf09b..4c26b0496c82 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-11-21 +date: 2023-11-27 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 4b5d1525d6b7..a87e196f1836 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-11-21 +date: 2023-11-27 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 feba597cc96d..4539b650bbb4 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-11-21 +date: 2023-11-27 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 33a3c406786f..90136cd9784e 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-11-21 +date: 2023-11-27 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 30f7bc3efe58..91bbb6bccfaa 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-11-21 +date: 2023-11-27 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 ba0a18d37204..d88c363df9a6 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-11-21 +date: 2023-11-27 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 f9d1c61dd66d..16f5248597f3 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-11-21 +date: 2023-11-27 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 45e0e1f4abdc..a5655f4688f0 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-11-21 +date: 2023-11-27 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 9798e5c54454..ce0af846f9b3 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_subscription_tracking.devdocs.json b/api_docs/kbn_subscription_tracking.devdocs.json deleted file mode 100644 index ea9cdb7f0716..000000000000 --- a/api_docs/kbn_subscription_tracking.devdocs.json +++ /dev/null @@ -1,519 +0,0 @@ -{ - "id": "@kbn/subscription-tracking", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.registerEvents", - "type": "Function", - "tags": [], - "label": "registerEvents", - "description": [ - "\nRegisters the subscription-specific event types" - ], - "signature": [ - "(analyticsClient: Pick<", - { - "pluginId": "@kbn/analytics-client", - "scope": "common", - "docId": "kibKbnAnalyticsClientPluginApi", - "section": "def-common.IAnalyticsClient", - "text": "IAnalyticsClient" - }, - ", \"registerEventType\">) => void" - ], - "path": "packages/kbn-subscription-tracking/src/services.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.registerEvents.$1", - "type": "Object", - "tags": [], - "label": "analyticsClient", - "description": [], - "signature": [ - "Pick<", - { - "pluginId": "@kbn/analytics-client", - "scope": "common", - "docId": "kibKbnAnalyticsClientPluginApi", - "section": "def-common.IAnalyticsClient", - "text": "IAnalyticsClient" - }, - ", \"registerEventType\">" - ], - "path": "packages/kbn-subscription-tracking/src/services.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButton", - "type": "Function", - "tags": [], - "label": "SubscriptionButton", - "description": [ - "\nWrapper around `EuiButton` that provides subscription events" - ], - "signature": [ - "({\n subscriptionContext,\n children,\n ...restProps\n}: ", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionButtonProps", - "text": "SubscriptionButtonProps" - }, - ") => JSX.Element" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButton.$1", - "type": "CompoundType", - "tags": [], - "label": "{\n subscriptionContext,\n children,\n ...restProps\n}", - "description": [], - "signature": [ - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionButtonProps", - "text": "SubscriptionButtonProps" - } - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButtonEmpty", - "type": "Function", - "tags": [], - "label": "SubscriptionButtonEmpty", - "description": [ - "\nWrapper around `EuiButtonEmpty` that provides subscription events" - ], - "signature": [ - "({\n subscriptionContext,\n children,\n ...restProps\n}: ", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionButtonEmptyProps", - "text": "SubscriptionButtonEmptyProps" - }, - ") => JSX.Element" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButtonEmpty.$1", - "type": "CompoundType", - "tags": [], - "label": "{\n subscriptionContext,\n children,\n ...restProps\n}", - "description": [], - "signature": [ - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionButtonEmptyProps", - "text": "SubscriptionButtonEmptyProps" - } - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionLink", - "type": "Function", - "tags": [], - "label": "SubscriptionLink", - "description": [ - "\nWrapper around `EuiLink` that provides subscription events" - ], - "signature": [ - "({\n subscriptionContext,\n children,\n ...restProps\n}: ", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionLinkProps", - "text": "SubscriptionLinkProps" - }, - ") => JSX.Element" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionLink.$1", - "type": "CompoundType", - "tags": [], - "label": "{\n subscriptionContext,\n children,\n ...restProps\n}", - "description": [], - "signature": [ - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.SubscriptionLinkProps", - "text": "SubscriptionLinkProps" - } - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionTrackingProvider", - "type": "Function", - "tags": [], - "label": "SubscriptionTrackingProvider", - "description": [ - "\nExternal services provider" - ], - "signature": [ - "({ children, ...services }: React.PropsWithChildren<", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.Services", - "text": "Services" - }, - ">) => JSX.Element" - ], - "path": "packages/kbn-subscription-tracking/src/services.tsx", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionTrackingProvider.$1", - "type": "CompoundType", - "tags": [], - "label": "{ children, ...services }", - "description": [], - "signature": [ - "React.PropsWithChildren<", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.Services", - "text": "Services" - }, - ">" - ], - "path": "packages/kbn-subscription-tracking/src/services.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services", - "type": "Interface", - "tags": [], - "label": "Services", - "description": [], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services.navigateToApp", - "type": "Function", - "tags": [], - "label": "navigateToApp", - "description": [], - "signature": [ - "(app: string, options: { path: string; }) => void" - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services.navigateToApp.$1", - "type": "string", - "tags": [], - "label": "app", - "description": [], - "signature": [ - "string" - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services.navigateToApp.$2", - "type": "Object", - "tags": [], - "label": "options", - "description": [], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services.navigateToApp.$2.path", - "type": "string", - "tags": [], - "label": "path", - "description": [], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - } - ], - "returnComment": [] - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.Services.analyticsClient", - "type": "Object", - "tags": [], - "label": "analyticsClient", - "description": [], - "signature": [ - "{ reportEvent: (eventType: string, eventData: EventTypeData) => void; }" - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionContextData", - "type": "Interface", - "tags": [], - "label": "SubscriptionContextData", - "description": [ - "\nA piece of metadata which consists of an identifier of the advertised feature and\nthe `source` (e.g. location) of the subscription element." - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionContextData.source", - "type": "CompoundType", - "tags": [], - "label": "source", - "description": [ - "\nA human-readable identifier describing the location of the beginning of the\nsubscription flow.\nLocation identifiers are prefixed with a solution identifier, e.g. `security__`\n" - ], - "signature": [ - "`observability__${string}` | `security__${string}`" - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionContextData.feature", - "type": "string", - "tags": [], - "label": "feature", - "description": [ - "\nA human-readable identifier describing the feature that is being promoted.\n" - ], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - } - ], - "enums": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.EVENT_NAMES", - "type": "Enum", - "tags": [], - "label": "EVENT_NAMES", - "description": [], - "path": "packages/kbn-subscription-tracking/types.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - } - ], - "misc": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButtonEmptyProps", - "type": "Type", - "tags": [], - "label": "SubscriptionButtonEmptyProps", - "description": [], - "signature": [ - "((", - "DisambiguateSet", - " & ", - "CommonEuiButtonEmptyProps", - " & { onClick?: React.MouseEventHandler | undefined; } & React.ButtonHTMLAttributes) | (", - "DisambiguateSet", - "<", - "EuiButtonEmptyPropsForButton", - ", EuiButtonEmptyPropsForAnchor> & ", - "CommonEuiButtonEmptyProps", - " & { href?: string | undefined; onClick?: React.MouseEventHandler | undefined; } & React.AnchorHTMLAttributes)) & CommonProps" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionButtonProps", - "type": "Type", - "tags": [], - "label": "SubscriptionButtonProps", - "description": [], - "signature": [ - "EuiButtonProps", - " & CommonProps" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionLinkProps", - "type": "Type", - "tags": [], - "label": "SubscriptionLinkProps", - "description": [], - "signature": [ - "((", - "DisambiguateSet", - "<", - "EuiLinkButtonProps", - ", ", - "EuiLinkAnchorProps", - "> & ", - "EuiLinkAnchorProps", - ") | (", - "DisambiguateSet", - "<", - "EuiLinkAnchorProps", - ", ", - "EuiLinkButtonProps", - "> & ", - "EuiLinkButtonProps", - ")) & CommonProps" - ], - "path": "packages/kbn-subscription-tracking/src/subscription_elements.tsx", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - } - ], - "objects": [ - { - "parentPluginId": "@kbn/subscription-tracking", - "id": "def-common.SubscriptionTrackingContext", - "type": "Object", - "tags": [], - "label": "SubscriptionTrackingContext", - "description": [], - "signature": [ - "React.Context<", - { - "pluginId": "@kbn/subscription-tracking", - "scope": "common", - "docId": "kibKbnSubscriptionTrackingPluginApi", - "section": "def-common.Services", - "text": "Services" - }, - " | null>" - ], - "path": "packages/kbn-subscription-tracking/src/services.tsx", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - } - ] - } -} \ No newline at end of file diff --git a/api_docs/kbn_subscription_tracking.mdx b/api_docs/kbn_subscription_tracking.mdx deleted file mode 100644 index 9273dfdfa1a6..000000000000 --- a/api_docs/kbn_subscription_tracking.mdx +++ /dev/null @@ -1,42 +0,0 @@ ---- -#### -#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. -#### Reach out in #docs-engineering for more info. -#### -id: kibKbnSubscriptionTrackingPluginApi -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-11-21 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/subscription-tracking'] ---- -import kbnSubscriptionTrackingObj from './kbn_subscription_tracking.devdocs.json'; - - - -Contact [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) for questions regarding this plugin. - -**Code health stats** - -| Public API count | Any count | Items lacking comments | Missing exports | -|-------------------|-----------|------------------------|-----------------| -| 24 | 0 | 16 | 0 | - -## Common - -### Objects - - -### Functions - - -### Interfaces - - -### Enums - - -### Consts, variables and types - - diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 35cc27ca79e4..4b10daac6831 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.devdocs.json b/api_docs/kbn_test.devdocs.json index 67c1c7a4a48c..68147342a7a5 100644 --- a/api_docs/kbn_test.devdocs.json +++ b/api_docs/kbn_test.devdocs.json @@ -3136,7 +3136,7 @@ "signature": [ "Pick<", "ServerlessOptions", - ", \"host\" | \"tag\" | \"image\" | \"resources\"> | undefined" + ", \"host\" | \"tag\" | \"image\" | \"resources\" | \"kibanaUrl\"> | undefined" ], "path": "packages/kbn-test/src/es/test_es_cluster.ts", "deprecated": false, diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 782ec763571e..150b46adba5c 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-11-21 +date: 2023-11-27 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 3dd1da7d64aa..fa4b11a399d5 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-11-21 +date: 2023-11-27 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 f63211ae1df1..d46fcbd84fd9 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_text_based_editor.devdocs.json index 252a6537ae63..69205611cafd 100644 --- a/api_docs/kbn_text_based_editor.devdocs.json +++ b/api_docs/kbn_text_based_editor.devdocs.json @@ -192,7 +192,9 @@ "type": "CompoundType", "tags": [], "label": "query", - "description": [], + "description": [ + "The aggregate type query" + ], "signature": [ "{ sql: string; } | { esql: string; }" ], @@ -206,7 +208,9 @@ "type": "Function", "tags": [], "label": "onTextLangQueryChange", - "description": [], + "description": [ + "Callback running everytime the query changes" + ], "signature": [ "(query: ", { @@ -252,14 +256,47 @@ "type": "Function", "tags": [], "label": "onTextLangQuerySubmit", - "description": [], + "description": [ + "Callback running when the user submits the query" + ], "signature": [ - "() => void" + "(query?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.AggregateQuery", + "text": "AggregateQuery" + }, + " | undefined) => void" ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.onTextLangQuerySubmit.$1", + "type": "CompoundType", + "tags": [], + "label": "query", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.AggregateQuery", + "text": "AggregateQuery" + }, + " | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], "returnComment": [] }, { @@ -268,7 +305,9 @@ "type": "Function", "tags": [], "label": "expandCodeEditor", - "description": [], + "description": [ + "Can be used to expand/minimize the editor" + ], "signature": [ "(status: boolean) => void" ], @@ -300,7 +339,9 @@ "type": "boolean", "tags": [], "label": "isCodeEditorExpanded", - "description": [], + "description": [ + "If it is true, the editor initializes with height EDITOR_INITIAL_HEIGHT_EXPANDED" + ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false @@ -311,7 +352,9 @@ "type": "CompoundType", "tags": [], "label": "detectTimestamp", - "description": [], + "description": [ + "If it is true, the editor displays the message @timestamp found\nThe text based queries are relying on adhoc dataviews which\ncan have an @timestamp timefield or nothing" + ], "signature": [ "boolean | undefined" ], @@ -325,7 +368,9 @@ "type": "Array", "tags": [], "label": "errors", - "description": [], + "description": [ + "Array of errors" + ], "signature": [ "Error[] | undefined" ], @@ -339,7 +384,9 @@ "type": "string", "tags": [], "label": "warning", - "description": [], + "description": [ + "Warning string as it comes from ES" + ], "signature": [ "string | undefined" ], @@ -353,7 +400,9 @@ "type": "CompoundType", "tags": [], "label": "isDisabled", - "description": [], + "description": [ + "Disables the editor" + ], "signature": [ "boolean | undefined" ], @@ -367,7 +416,9 @@ "type": "CompoundType", "tags": [], "label": "isDarkMode", - "description": [], + "description": [ + "Indicator if the editor is on dark mode" + ], "signature": [ "boolean | undefined" ], @@ -395,7 +446,9 @@ "type": "CompoundType", "tags": [], "label": "hideMinimizeButton", - "description": [], + "description": [ + "If true it hides the minimize button and the user can't return to the minimized version\nUseful when the application doesn't want to give this capability" + ], "signature": [ "boolean | undefined" ], @@ -409,7 +462,41 @@ "type": "CompoundType", "tags": [], "label": "hideRunQueryText", - "description": [], + "description": [ + "Hide the Run query information which appears on the footer" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.editorIsInline", + "type": "CompoundType", + "tags": [], + "label": "editorIsInline", + "description": [ + "This is used for applications (such as the inline editing flyout in dashboards)\nwhich want to add the editor without being part of the Unified search component\nIt renders a submit query button inside the editor" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/text-based-editor", + "id": "def-public.TextBasedLanguagesEditorProps.disableSubmitAction", + "type": "CompoundType", + "tags": [], + "label": "disableSubmitAction", + "description": [ + "Disables the submit query action" + ], "signature": [ "boolean | undefined" ], diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 1d29acdde4af..5674730d4458 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 22 | 0 | 21 | 0 | +| 25 | 0 | 10 | 0 | ## Client diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index da958cebd845..724ec829f943 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-11-21 +date: 2023-11-27 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 1d8534e9fb3a..39614d3fd634 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-11-21 +date: 2023-11-27 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 20708e11cee2..026d331f9d74 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_ui_actions_browser.devdocs.json index 7a589d952a59..aabb32029e0d 100644 --- a/api_docs/kbn_ui_actions_browser.devdocs.json +++ b/api_docs/kbn_ui_actions_browser.devdocs.json @@ -438,21 +438,6 @@ ], "enums": [], "misc": [ - { - "parentPluginId": "@kbn/ui-actions-browser", - "id": "def-common.CATEGORIZE_FIELD_TRIGGER", - "type": "string", - "tags": [], - "label": "CATEGORIZE_FIELD_TRIGGER", - "description": [], - "signature": [ - "\"CATEGORIZE_FIELD_TRIGGER\"" - ], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "@kbn/ui-actions-browser", "id": "def-common.PresentableGrouping", @@ -522,53 +507,6 @@ } ], "objects": [ - { - "parentPluginId": "@kbn/ui-actions-browser", - "id": "def-common.categorizeFieldTrigger", - "type": "Object", - "tags": [], - "label": "categorizeFieldTrigger", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/ui-actions-browser", - "id": "def-common.categorizeFieldTrigger.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/ui-actions-browser", - "id": "def-common.categorizeFieldTrigger.title", - "type": "string", - "tags": [], - "label": "title", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "@kbn/ui-actions-browser", - "id": "def-common.categorizeFieldTrigger.description", - "type": "string", - "tags": [], - "label": "description", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "@kbn/ui-actions-browser", "id": "def-common.defaultTrigger", diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 030069abf84c..373cdd85e650 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 49 | 0 | 35 | 0 | +| 44 | 0 | 30 | 0 | ## Common diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 0d69082ef1ca..e11d759582aa 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-11-21 +date: 2023-11-27 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 f067c6d18e68..bd54964199e9 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-11-21 +date: 2023-11-27 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 e072f1adf9c1..8cd81175eea9 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-11-21 +date: 2023-11-27 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 113cc75baeae..209fa6301fdc 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-11-21 +date: 2023-11-27 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.devdocs.json b/api_docs/kbn_unified_field_list.devdocs.json index 20244ca1fb58..35da28a598da 100644 --- a/api_docs/kbn_unified_field_list.devdocs.json +++ b/api_docs/kbn_unified_field_list.devdocs.json @@ -4171,15 +4171,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -4195,17 +4197,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 9e49d8e9b662..e2cd4a8488d3 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_unsaved_changes_badge.mdx b/api_docs/kbn_unsaved_changes_badge.mdx index 37ea9f303e50..b1d2e3041223 100644 --- a/api_docs/kbn_unsaved_changes_badge.mdx +++ b/api_docs/kbn_unsaved_changes_badge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unsaved-changes-badge title: "@kbn/unsaved-changes-badge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unsaved-changes-badge plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 58bb87a765ad..6141bef6013c 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-11-21 +date: 2023-11-27 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 3d63e715cb4f..58061d0eb930 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-11-21 +date: 2023-11-27 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 cb8eb608b941..c9b6438fc04b 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-11-21 +date: 2023-11-27 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 1cfc9e7bd163..4f7225cbd909 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-11-21 +date: 2023-11-27 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 c1f18027fc66..a30033a18d6e 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-11-21 +date: 2023-11-27 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 ae9f9ea0ee5e..e9afd296ad9d 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-11-21 +date: 2023-11-27 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 73830e2d04db..a97d09369ea4 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-11-21 +date: 2023-11-27 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 486044b0a279..7990eaa42290 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-11-21 +date: 2023-11-27 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 9debee10dff4..749d0a7b6a55 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index 045dc345ae55..86d2072c5122 100644 --- a/api_docs/kbn_zod_helpers.mdx +++ b/api_docs/kbn_zod_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-zod-helpers title: "@kbn/zod-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/zod-helpers plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/zod-helpers'] --- import kbnZodHelpersObj from './kbn_zod_helpers.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 64c56fa357f4..927238442c36 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-11-21 +date: 2023-11-27 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 15e6f3725eab..68a511a501fd 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-11-21 +date: 2023-11-27 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 0d76b07b1a55..3258c5542e57 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-11-21 +date: 2023-11-27 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 dfa21718784c..1b2658a7a359 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index 0808aafa7726..cf20e0cb4737 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -360,7 +360,7 @@ "\nGets the Lens embeddable's datasource and visualization states\nupdates the embeddable input" ], "signature": [ - "(datasourceState: unknown, visualizationState: unknown) => Promise" + "(datasourceState: unknown, visualizationState: unknown, visualizationType?: string | undefined) => Promise" ], "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", "deprecated": false, @@ -395,6 +395,67 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "lens", + "id": "def-public.Embeddable.updateVisualization.$3", + "type": "string", + "tags": [], + "label": "visualizationType", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "lens", + "id": "def-public.Embeddable.updateSuggestion", + "type": "Function", + "tags": [], + "label": "updateSuggestion", + "description": [], + "signature": [ + "(attrs: ", + { + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.LensSavedObjectAttributes", + "text": "LensSavedObjectAttributes" + }, + ") => Promise" + ], + "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Embeddable.updateSuggestion.$1", + "type": "Object", + "tags": [], + "label": "attrs", + "description": [], + "signature": [ + { + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.LensSavedObjectAttributes", + "text": "LensSavedObjectAttributes" + } + ], + "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -5131,6 +5192,20 @@ "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.SuggestionRequest.datasourceId", + "type": "string", + "tags": [], + "label": "datasourceId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -5222,6 +5297,20 @@ "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "lens", + "id": "def-public.TableSuggestion.notAssignedMetrics", + "type": "CompoundType", + "tags": [], + "label": "notAssignedMetrics", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -6375,7 +6464,7 @@ "label": "getRemoveOperation", "description": [], "signature": [ - "((state: T, layerId: string) => \"remove\" | \"clear\") | undefined" + "((state: T, layerId: string) => \"clear\" | \"remove\") | undefined" ], "path": "x-pack/plugins/lens/public/types.ts", "deprecated": false, diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index f15b4eca50c2..c2ae6633dd6b 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 625 | 0 | 526 | 60 | +| 630 | 0 | 531 | 60 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 091d06c133ae..069137a6c773 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-11-21 +date: 2023-11-27 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 d44c992a0c2c..e2a699802d04 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-11-21 +date: 2023-11-27 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 b23db6581fdc..233e4fb114d4 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/links.devdocs.json b/api_docs/links.devdocs.json index d688e23b9f15..24744659d473 100644 --- a/api_docs/links.devdocs.json +++ b/api_docs/links.devdocs.json @@ -80,98 +80,14 @@ }, { "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.select", - "type": "Function", - "tags": [], - "label": "select", - "description": [ - "\nTODO: Keep track of the necessary state without the redux embeddable tools; it's kind of overkill here.\n Related issue: https://github.com/elastic/kibana/issues/167577" - ], - "signature": [ - "(selector: (state: ", - "LinksReduxState", - ") => Selected, equalityFn?: ((previous: Selected, next: Selected) => boolean) | undefined) => Selected" - ], - "path": "src/plugins/links/public/embeddable/links_embeddable.tsx", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.select.$1", - "type": "Function", - "tags": [], - "label": "selector", - "description": [], - "signature": [ - "(state: ReduxStateType) => Selected" - ], - "path": "src/plugins/presentation_util/public/redux_tools/types.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.select.$1.$1", - "type": "Uncategorized", - "tags": [], - "label": "state", - "description": [], - "signature": [ - "ReduxStateType" - ], - "path": "src/plugins/presentation_util/public/redux_tools/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - }, - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.select.$2", - "type": "Function", - "tags": [], - "label": "equalityFn", - "description": [], - "signature": [ - "((previous: Selected, next: Selected) => boolean) | undefined" - ], - "path": "src/plugins/presentation_util/public/redux_tools/types.ts", - "deprecated": false, - "trackAdoption": false - } - ] - }, - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.getState", - "type": "Function", - "tags": [], - "label": "getState", - "description": [], - "signature": [ - "() => ", - "LinksReduxState" - ], - "path": "src/plugins/links/public/embeddable/links_embeddable.tsx", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [] - }, - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.dispatch", + "id": "def-public.LinksEmbeddable.attributes", "type": "Object", "tags": [], - "label": "dispatch", + "label": "attributes", "description": [], "signature": [ - "{ setLoading: (payload: boolean) => void; setAttributes: (payload: ", "LinksAttributes", - ") => void; }" + " | undefined" ], "path": "src/plugins/links/public/embeddable/links_embeddable.tsx", "deprecated": false, @@ -179,37 +95,20 @@ }, { "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.onStateChange", - "type": "Function", + "id": "def-public.LinksEmbeddable.attributes$", + "type": "Object", "tags": [], - "label": "onStateChange", + "label": "attributes$", "description": [], "signature": [ - "(listener: () => void) => ", - "Unsubscribe" + "Subject", + "<", + "LinksAttributes", + ">" ], "path": "src/plugins/links/public/embeddable/links_embeddable.tsx", "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.onStateChange.$1", - "type": "Function", - "tags": [], - "label": "listener", - "description": [], - "signature": [ - "() => void" - ], - "path": "node_modules/redux/index.d.ts", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [] - } - ] + "trackAdoption": false }, { "parentPluginId": "links", @@ -230,27 +129,6 @@ "id": "def-public.LinksEmbeddable.Unnamed.$1", "type": "Object", "tags": [], - "label": "reduxToolsPackage", - "description": [], - "signature": [ - { - "pluginId": "presentationUtil", - "scope": "public", - "docId": "kibPresentationUtilPluginApi", - "section": "def-public.ReduxToolsPackage", - "text": "ReduxToolsPackage" - } - ], - "path": "src/plugins/links/public/embeddable/links_embeddable.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.Unnamed.$2", - "type": "Object", - "tags": [], "label": "config", "description": [], "signature": [ @@ -263,7 +141,7 @@ }, { "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.Unnamed.$3", + "id": "def-public.LinksEmbeddable.Unnamed.$2", "type": "CompoundType", "tags": [], "label": "initialInput", @@ -278,7 +156,7 @@ }, { "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.Unnamed.$4", + "id": "def-public.LinksEmbeddable.Unnamed.$3", "type": "Object", "tags": [], "label": "attributeService", @@ -320,7 +198,7 @@ }, { "parentPluginId": "links", - "id": "def-public.LinksEmbeddable.Unnamed.$5", + "id": "def-public.LinksEmbeddable.Unnamed.$4", "type": "Object", "tags": [], "label": "parent", diff --git a/api_docs/links.mdx b/api_docs/links.mdx index e77b2d86d9bd..2eabc3b73e8d 100644 --- a/api_docs/links.mdx +++ b/api_docs/links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/links title: "links" image: https://source.unsplash.com/400x175/?github description: API docs for the links plugin -date: 2023-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'links'] --- import linksObj from './links.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 64 | 0 | 62 | 7 | +| 57 | 0 | 57 | 6 | ## Client diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 5b5a940efadc..59c66016f9b7 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-11-21 +date: 2023-11-27 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 24d9d3b82f0b..19ab86816dc1 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logExplorer'] --- import logExplorerObj from './log_explorer.devdocs.json'; diff --git a/api_docs/logs_shared.devdocs.json b/api_docs/logs_shared.devdocs.json index 5e35354e0187..61da0f6f1007 100644 --- a/api_docs/logs_shared.devdocs.json +++ b/api_docs/logs_shared.devdocs.json @@ -2878,15 +2878,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -2902,17 +2904,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 599557e17c8c..4b99c262a299 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-11-21 +date: 2023-11-27 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 8d362cce9f08..f1d960313faa 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-11-21 +date: 2023-11-27 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 a301fe296830..424e384ffcc8 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-11-21 +date: 2023-11-27 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 b107dbfa783d..a70a9d3f6b16 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-11-21 +date: 2023-11-27 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 b3baddff3454..14b86a2e2fe7 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index f3254ea9f455..2c947c4c6a90 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -1045,7 +1045,7 @@ "label": "ML_PAGES", "description": [], "signature": [ - "{ readonly ANOMALY_DETECTION_JOBS_MANAGE: \"jobs\"; readonly ANOMALY_EXPLORER: \"explorer\"; readonly SINGLE_METRIC_VIEWER: \"timeseriesexplorer\"; readonly DATA_FRAME_ANALYTICS_JOBS_MANAGE: \"data_frame_analytics\"; readonly DATA_FRAME_ANALYTICS_SOURCE_SELECTION: \"data_frame_analytics/source_selection\"; readonly DATA_FRAME_ANALYTICS_CREATE_JOB: \"data_frame_analytics/new_job\"; readonly TRAINED_MODELS_MANAGE: \"trained_models\"; readonly DATA_DRIFT_INDEX_SELECT: \"data_drift_index_select\"; readonly DATA_DRIFT_CUSTOM: \"data_drift_custom\"; readonly DATA_DRIFT: \"data_drift\"; readonly NODES: \"nodes\"; readonly MEMORY_USAGE: \"memory_usage\"; readonly DATA_FRAME_ANALYTICS_EXPLORATION: \"data_frame_analytics/exploration\"; readonly DATA_FRAME_ANALYTICS_MAP: \"data_frame_analytics/map\"; readonly DATA_VISUALIZER: \"datavisualizer\"; readonly DATA_VISUALIZER_INDEX_SELECT: \"datavisualizer_index_select\"; readonly DATA_VISUALIZER_FILE: \"filedatavisualizer\"; readonly DATA_VISUALIZER_INDEX_VIEWER: \"jobs/new_job/datavisualizer\"; readonly ANOMALY_DETECTION_CREATE_JOB: \"jobs/new_job\"; readonly ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER: \"jobs/new_job/recognize\"; readonly ANOMALY_DETECTION_CREATE_JOB_SINGLE_METRIC: \"jobs/new_job/single_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_MULTI_METRIC: \"jobs/new_job/multi_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_MULTI_METRIC: \"jobs/new_job/convert_to_multi_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_ADVANCED: \"jobs/new_job/advanced\"; readonly ANOMALY_DETECTION_CREATE_JOB_POPULATION: \"jobs/new_job/population\"; readonly ANOMALY_DETECTION_CREATE_JOB_CATEGORIZATION: \"jobs/new_job/categorization\"; readonly ANOMALY_DETECTION_CREATE_JOB_RARE: \"jobs/new_job/rare\"; readonly ANOMALY_DETECTION_CREATE_JOB_GEO: \"jobs/new_job/geo\"; readonly ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_ADVANCED: \"jobs/new_job/convert_to_advanced\"; readonly ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: \"jobs/new_job/step/job_type\"; readonly ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: \"jobs/new_job/step/index_or_search\"; readonly ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: \"jobs/new_job/from_lens\"; readonly ANOMALY_DETECTION_CREATE_JOB_FROM_MAP: \"jobs/new_job/from_map\"; readonly ANOMALY_DETECTION_MODULES_VIEW_OR_CREATE: \"modules/check_view_or_create\"; readonly SETTINGS: \"settings\"; readonly CALENDARS_MANAGE: \"settings/calendars_list\"; readonly CALENDARS_NEW: \"settings/calendars_list/new_calendar\"; readonly CALENDARS_EDIT: \"settings/calendars_list/edit_calendar\"; readonly FILTER_LISTS_MANAGE: \"settings/filter_lists\"; readonly FILTER_LISTS_NEW: \"settings/filter_lists/new_filter_list\"; readonly FILTER_LISTS_EDIT: \"settings/filter_lists/edit_filter_list\"; readonly OVERVIEW: \"overview\"; readonly NOTIFICATIONS: \"notifications\"; readonly AIOPS: \"aiops\"; readonly AIOPS_EXPLAIN_LOG_RATE_SPIKES: \"aiops/explain_log_rate_spikes\"; readonly AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT: \"aiops/explain_log_rate_spikes_index_select\"; readonly AIOPS_LOG_RATE_ANALYSIS: \"aiops/log_rate_analysis\"; readonly AIOPS_LOG_RATE_ANALYSIS_INDEX_SELECT: \"aiops/log_rate_analysis_index_select\"; readonly AIOPS_LOG_CATEGORIZATION: \"aiops/log_categorization\"; readonly AIOPS_LOG_CATEGORIZATION_INDEX_SELECT: \"aiops/log_categorization_index_select\"; readonly AIOPS_CHANGE_POINT_DETECTION: \"aiops/change_point_detection\"; readonly AIOPS_CHANGE_POINT_DETECTION_INDEX_SELECT: \"aiops/change_point_detection_index_select\"; }" + "{ readonly ANOMALY_DETECTION_JOBS_MANAGE: \"jobs\"; readonly ANOMALY_EXPLORER: \"explorer\"; readonly SINGLE_METRIC_VIEWER: \"timeseriesexplorer\"; readonly DATA_FRAME_ANALYTICS_JOBS_MANAGE: \"data_frame_analytics\"; readonly DATA_FRAME_ANALYTICS_SOURCE_SELECTION: \"data_frame_analytics/source_selection\"; readonly DATA_FRAME_ANALYTICS_CREATE_JOB: \"data_frame_analytics/new_job\"; readonly TRAINED_MODELS_MANAGE: \"trained_models\"; readonly DATA_DRIFT_INDEX_SELECT: \"data_drift_index_select\"; readonly DATA_DRIFT_CUSTOM: \"data_drift_custom\"; readonly DATA_DRIFT: \"data_drift\"; readonly NODES: \"nodes\"; readonly MEMORY_USAGE: \"memory_usage\"; readonly DATA_FRAME_ANALYTICS_EXPLORATION: \"data_frame_analytics/exploration\"; readonly DATA_FRAME_ANALYTICS_MAP: \"data_frame_analytics/map\"; readonly DATA_VISUALIZER: \"datavisualizer\"; readonly DATA_VISUALIZER_INDEX_SELECT: \"datavisualizer_index_select\"; readonly DATA_VISUALIZER_FILE: \"filedatavisualizer\"; readonly DATA_VISUALIZER_INDEX_VIEWER: \"jobs/new_job/datavisualizer\"; readonly ANOMALY_DETECTION_CREATE_JOB: \"jobs/new_job\"; readonly ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER: \"jobs/new_job/recognize\"; readonly ANOMALY_DETECTION_CREATE_JOB_SINGLE_METRIC: \"jobs/new_job/single_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_MULTI_METRIC: \"jobs/new_job/multi_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_MULTI_METRIC: \"jobs/new_job/convert_to_multi_metric\"; readonly ANOMALY_DETECTION_CREATE_JOB_ADVANCED: \"jobs/new_job/advanced\"; readonly ANOMALY_DETECTION_CREATE_JOB_POPULATION: \"jobs/new_job/population\"; readonly ANOMALY_DETECTION_CREATE_JOB_CATEGORIZATION: \"jobs/new_job/categorization\"; readonly ANOMALY_DETECTION_CREATE_JOB_RARE: \"jobs/new_job/rare\"; readonly ANOMALY_DETECTION_CREATE_JOB_GEO: \"jobs/new_job/geo\"; readonly ANOMALY_DETECTION_CREATE_JOB_CONVERT_TO_ADVANCED: \"jobs/new_job/convert_to_advanced\"; readonly ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: \"jobs/new_job/step/job_type\"; readonly ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: \"jobs/new_job/step/index_or_search\"; readonly ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: \"jobs/new_job/from_lens\"; readonly ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS: \"jobs/new_job/from_pattern_analysis\"; readonly ANOMALY_DETECTION_CREATE_JOB_FROM_MAP: \"jobs/new_job/from_map\"; readonly ANOMALY_DETECTION_MODULES_VIEW_OR_CREATE: \"modules/check_view_or_create\"; readonly SETTINGS: \"settings\"; readonly CALENDARS_MANAGE: \"settings/calendars_list\"; readonly CALENDARS_NEW: \"settings/calendars_list/new_calendar\"; readonly CALENDARS_EDIT: \"settings/calendars_list/edit_calendar\"; readonly FILTER_LISTS_MANAGE: \"settings/filter_lists\"; readonly FILTER_LISTS_NEW: \"settings/filter_lists/new_filter_list\"; readonly FILTER_LISTS_EDIT: \"settings/filter_lists/edit_filter_list\"; readonly OVERVIEW: \"overview\"; readonly NOTIFICATIONS: \"notifications\"; readonly AIOPS: \"aiops\"; readonly AIOPS_EXPLAIN_LOG_RATE_SPIKES: \"aiops/explain_log_rate_spikes\"; readonly AIOPS_EXPLAIN_LOG_RATE_SPIKES_INDEX_SELECT: \"aiops/explain_log_rate_spikes_index_select\"; readonly AIOPS_LOG_RATE_ANALYSIS: \"aiops/log_rate_analysis\"; readonly AIOPS_LOG_RATE_ANALYSIS_INDEX_SELECT: \"aiops/log_rate_analysis_index_select\"; readonly AIOPS_LOG_CATEGORIZATION: \"aiops/log_categorization\"; readonly AIOPS_LOG_CATEGORIZATION_INDEX_SELECT: \"aiops/log_categorization_index_select\"; readonly AIOPS_CHANGE_POINT_DETECTION: \"aiops/change_point_detection\"; readonly AIOPS_CHANGE_POINT_DETECTION_INDEX_SELECT: \"aiops/change_point_detection_index_select\"; }" ], "path": "x-pack/plugins/ml/common/constants/locator.ts", "deprecated": false, diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index fd51fef94cf7..3db9f81af55a 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/mock_idp_plugin.devdocs.json b/api_docs/mock_idp_plugin.devdocs.json new file mode 100644 index 000000000000..9c7b5bd1558d --- /dev/null +++ b/api_docs/mock_idp_plugin.devdocs.json @@ -0,0 +1,410 @@ +{ + "id": "mockIdpPlugin", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createMockIdpMetadata", + "type": "Function", + "tags": [], + "label": "createMockIdpMetadata", + "description": [ + "\nCreates XML metadata for our mock identity provider.\n\nThis can be saved to file and used to configure Elasticsearch SAML realm.\n" + ], + "signature": [ + "(kibanaUrl: string) => Promise" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createMockIdpMetadata.$1", + "type": "string", + "tags": [], + "label": "kibanaUrl", + "description": [ + "Fully qualified URL where Kibana is hosted (including base path)" + ], + "signature": [ + "string" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse", + "type": "Function", + "tags": [], + "label": "createSAMLResponse", + "description": [ + "\nCreates a SAML response that can be passed directly to the Kibana ACS endpoint to authenticate a user.\n" + ], + "signature": [ + "(options: { kibanaUrl: string; authnRequestId?: string | undefined; username: string; fullname?: string | undefined; email?: string | undefined; roles: string[]; }) => Promise" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.kibanaUrl", + "type": "string", + "tags": [], + "label": "kibanaUrl", + "description": [ + "Fully qualified URL where Kibana is hosted (including base path)" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.authnRequestId", + "type": "string", + "tags": [], + "label": "authnRequestId", + "description": [ + "ID from SAML authentication request" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.username", + "type": "string", + "tags": [], + "label": "username", + "description": [], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.fullname", + "type": "string", + "tags": [], + "label": "fullname", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.email", + "type": "string", + "tags": [], + "label": "email", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.createSAMLResponse.$1.roles", + "type": "Array", + "tags": [], + "label": "roles", + "description": [], + "signature": [ + "string[]" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.ensureSAMLRoleMapping", + "type": "Function", + "tags": [], + "label": "ensureSAMLRoleMapping", + "description": [ + "\nCreates the role mapping required for developers to authenticate using SAML." + ], + "signature": [ + "(client: ", + "default", + ") => Promise" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.ensureSAMLRoleMapping.$1", + "type": "Object", + "tags": [], + "label": "client", + "description": [], + "signature": [ + "default" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.parseSAMLAuthnRequest", + "type": "Function", + "tags": [], + "label": "parseSAMLAuthnRequest", + "description": [], + "signature": [ + "(samlRequest: string) => Promise<{ AssertionConsumerServiceURL: string; Destination: string; ID: string; IssueInstant: string; }>" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.parseSAMLAuthnRequest.$1", + "type": "string", + "tags": [], + "label": "samlRequest", + "description": [], + "signature": [ + "string" + ], + "path": "packages/kbn-mock-idp-plugin/common/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [ + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ATTRIBUTE_EMAIL", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ATTRIBUTE_EMAIL", + "description": [], + "signature": [ + "\"http://saml.elastic-cloud.com/attributes/email\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ATTRIBUTE_NAME", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ATTRIBUTE_NAME", + "description": [], + "signature": [ + "\"http://saml.elastic-cloud.com/attributes/name\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ATTRIBUTE_PRINCIPAL", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ATTRIBUTE_PRINCIPAL", + "description": [], + "signature": [ + "\"http://saml.elastic-cloud.com/attributes/principal\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ATTRIBUTE_ROLES", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ATTRIBUTE_ROLES", + "description": [], + "signature": [ + "\"http://saml.elastic-cloud.com/attributes/roles\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ENTITY_ID", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ENTITY_ID", + "description": [], + "signature": [ + "\"urn:mock-idp\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_LOGIN_PATH", + "type": "string", + "tags": [], + "label": "MOCK_IDP_LOGIN_PATH", + "description": [], + "signature": [ + "\"/mock_idp/login\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_LOGOUT_PATH", + "type": "string", + "tags": [], + "label": "MOCK_IDP_LOGOUT_PATH", + "description": [], + "signature": [ + "\"/mock_idp/logout\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_METADATA_PATH", + "type": "string", + "tags": [], + "label": "MOCK_IDP_METADATA_PATH", + "description": [], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_PLUGIN_PATH", + "type": "string", + "tags": [], + "label": "MOCK_IDP_PLUGIN_PATH", + "description": [], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_REALM_NAME", + "type": "string", + "tags": [], + "label": "MOCK_IDP_REALM_NAME", + "description": [], + "signature": [ + "\"mock-idp\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "mockIdpPlugin", + "id": "def-common.MOCK_IDP_ROLE_MAPPING_NAME", + "type": "string", + "tags": [], + "label": "MOCK_IDP_ROLE_MAPPING_NAME", + "description": [], + "signature": [ + "\"mock-idp-mapping\"" + ], + "path": "packages/kbn-mock-idp-plugin/common/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/mock_idp_plugin.mdx b/api_docs/mock_idp_plugin.mdx new file mode 100644 index 000000000000..bf3eb9327f9e --- /dev/null +++ b/api_docs/mock_idp_plugin.mdx @@ -0,0 +1,33 @@ +--- +#### +#### This document is auto-generated and is meant to be viewed inside our experimental, new docs system. +#### Reach out in #docs-engineering for more info. +#### +id: kibMockIdpPluginPluginApi +slug: /kibana-dev-docs/api/mockIdpPlugin +title: "mockIdpPlugin" +image: https://source.unsplash.com/400x175/?github +description: API docs for the mockIdpPlugin plugin +date: 2023-11-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mockIdpPlugin'] +--- +import mockIdpPluginObj from './mock_idp_plugin.devdocs.json'; + + + +Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 25 | 0 | 19 | 0 | + +## Common + +### Functions + + +### Consts, variables and types + + diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index b3da30cf84eb..3de6b07448f9 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-11-21 +date: 2023-11-27 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 69a47820bf08..a53cfe9d987b 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-11-21 +date: 2023-11-27 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 f4a834374010..2b8489d665d3 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-11-21 +date: 2023-11-27 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 515bcb3e629a..a803bbafe410 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-11-21 +date: 2023-11-27 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 3ab4fa66b297..484b053110b4 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-11-21 +date: 2023-11-27 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 36b41b51f574..242532a1aab4 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-11-21 +date: 2023-11-27 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 b664fe6968a1..8728f898e2e4 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.devdocs.json b/api_docs/observability_a_i_assistant.devdocs.json index 29b5cec0de50..643513280895 100644 --- a/api_docs/observability_a_i_assistant.devdocs.json +++ b/api_docs/observability_a_i_assistant.devdocs.json @@ -19,7 +19,7 @@ "section": "def-common.Message", "text": "Message" }, - "[]; title: string; } & ", + "[]; title: string; dataTestSubj?: string | undefined; } & ", { "pluginId": "@kbn/shared-ux-utility", "scope": "common", diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 2be9d6e63156..b7da8c572742 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-11-21 +date: 2023-11-27 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 9053799ca3c5..2d810617fe9b 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-11-21 +date: 2023-11-27 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 d53de7acc2f4..f7783776af67 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.devdocs.json b/api_docs/observability_shared.devdocs.json index e8ab113a22cf..3032e49529bf 100644 --- a/api_docs/observability_shared.devdocs.json +++ b/api_docs/observability_shared.devdocs.json @@ -414,6 +414,53 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBar", + "type": "Function", + "tags": [], + "label": "EmbeddableProfilingSearchBar", + "description": [], + "signature": [ + "(props: ", + { + "pluginId": "observabilityShared", + "scope": "public", + "docId": "kibObservabilitySharedPluginApi", + "section": "def-public.EmbeddableProfilingSearchBarProps", + "text": "EmbeddableProfilingSearchBarProps" + }, + ") => JSX.Element" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBar.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + { + "pluginId": "observabilityShared", + "scope": "public", + "docId": "kibObservabilitySharedPluginApi", + "section": "def-public.EmbeddableProfilingSearchBarProps", + "text": "EmbeddableProfilingSearchBarProps" + } + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "observabilityShared", "id": "def-public.getContextMenuItemsFromActions", @@ -471,15 +518,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -495,17 +544,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", @@ -1912,6 +1959,138 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps", + "type": "Interface", + "tags": [], + "label": "EmbeddableProfilingSearchBarProps", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.kuery", + "type": "string", + "tags": [], + "label": "kuery", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.showDatePicker", + "type": "CompoundType", + "tags": [], + "label": "showDatePicker", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.onQuerySubmit", + "type": "Function", + "tags": [], + "label": "onQuerySubmit", + "description": [], + "signature": [ + "(params: { dateRange: { from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }; query: string; }) => void" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.onQuerySubmit.$1", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.onQuerySubmit.$1.dateRange", + "type": "Object", + "tags": [], + "label": "dateRange", + "description": [], + "signature": [ + "{ from: string; to: string; mode?: \"absolute\" | \"relative\" | undefined; }" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.onQuerySubmit.$1.query", + "type": "string", + "tags": [], + "label": "query", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [] + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.onRefresh", + "type": "Function", + "tags": [], + "label": "onRefresh", + "description": [], + "signature": [ + "() => void" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.rangeFrom", + "type": "string", + "tags": [], + "label": "rangeFrom", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EmbeddableProfilingSearchBarProps.rangeTo", + "type": "string", + "tags": [], + "label": "rangeTo", + "description": [], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "observabilityShared", "id": "def-public.FetcherResult", @@ -2620,6 +2799,23 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observabilityShared", + "id": "def-public.EMBEDDABLE_PROFILING_SEARCH_BAR", + "type": "string", + "tags": [], + "label": "EMBEDDABLE_PROFILING_SEARCH_BAR", + "description": [ + "Profiling search bar embeddable key" + ], + "signature": [ + "\"EMBEDDABLE_PROFILING_SEARCH_BAR\"" + ], + "path": "x-pack/plugins/observability_shared/public/components/profiling/embeddables/index.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observabilityShared", "id": "def-public.LazyObservabilityPageTemplateProps", diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index d81c20b49001..7205b558309c 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observ | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 292 | 1 | 289 | 15 | +| 305 | 1 | 301 | 15 | ## Client diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 631e0b097106..c4a722dd15b3 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-11-21 +date: 2023-11-27 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 e9fbdf587dbf..6757217c1742 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-11-21 +date: 2023-11-27 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 631c90f2dd3f..0a59a76a55af 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -15,13 +15,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Count | Plugins or Packages with a
    public API | Number of teams | |--------------|----------|------------------------| -| 714 | 606 | 40 | +| 715 | 607 | 40 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 76426 | 235 | 65361 | 1606 | +| 76458 | 235 | 65365 | 1609 | ## Plugin Directory @@ -29,8 +29,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] |--------------|----------------|-----------|--------------|----------|---------------|--------| | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 269 | 0 | 263 | 31 | | | [@elastic/appex-sharedux @elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 17 | 1 | 15 | 2 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 69 | 1 | 4 | 1 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 810 | 1 | 779 | 50 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 70 | 1 | 4 | 1 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 811 | 1 | 780 | 51 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | The user interface for Elastic APM | 29 | 0 | 29 | 120 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 9 | 0 | 9 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Asset manager plugin for entity assets (inventory, topology, etc) | 9 | 0 | 9 | 2 | @@ -62,7 +62,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 922 | 0 | 257 | 4 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | -| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 4 | 0 | 4 | 0 | +| | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 8 | 0 | 8 | 3 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 133 | 0 | 90 | 20 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | @@ -118,11 +118,11 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 610 | 3 | 417 | 9 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 5 | 0 | 5 | 1 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 625 | 0 | 526 | 60 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 630 | 0 | 531 | 60 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 8 | 0 | 8 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | A dashboard panel for creating links to dashboards or external links. | 64 | 0 | 62 | 7 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | A dashboard panel for creating links to dashboards or external links. | 57 | 0 | 57 | 6 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 224 | 0 | 96 | 51 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin provides a LogExplorer component using the Discover customization framework, offering several affordances specifically designed for log consumption. | 26 | 0 | 26 | 8 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | Exposes the shared components and APIs to access and visualize logs. | 289 | 11 | 274 | 27 | @@ -132,6 +132,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | - | 60 | 0 | 60 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | Exposes utilities for accessing metrics data | 104 | 8 | 104 | 4 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 150 | 3 | 64 | 33 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 25 | 0 | 19 | 0 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 15 | 3 | 13 | 1 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 35 | 0 | 35 | 2 | @@ -142,7 +143,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 42 | 0 | 39 | 7 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin exposes and registers observability log consumption features. | 15 | 0 | 15 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 14 | 0 | 14 | 0 | -| | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 292 | 1 | 289 | 15 | +| | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 305 | 1 | 301 | 15 | | | [@elastic/security-defend-workflows](https://github.com/orgs/elastic/teams/security-defend-workflows) | - | 24 | 0 | 24 | 7 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 2 | 0 | 2 | 0 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 219 | 2 | 164 | 11 | @@ -151,7 +152,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 23 | 0 | 23 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 22 | 0 | 6 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 21 | 0 | 21 | 0 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 267 | 0 | 238 | 14 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 268 | 0 | 239 | 14 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 24 | 0 | 19 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 129 | 2 | 118 | 4 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 25 | 0 | 25 | 0 | @@ -163,7 +164,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 32 | 0 | 8 | 4 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 270 | 0 | 87 | 3 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 175 | 0 | 106 | 35 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 175 | 0 | 106 | 34 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 7 | 0 | 7 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | The core Serverless plugin, providing APIs to Serverless Project plugins. | 19 | 0 | 18 | 0 | @@ -181,13 +182,13 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 31 | 0 | 26 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 0 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 20 | 0 | 20 | 0 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 23 | 0 | 9 | 0 | | | [@elastic/protections-experience](https://github.com/orgs/elastic/teams/protections-experience) | Elastic threat intelligence helps you see if you are open to or have been subject to current or historical known threats | 30 | 0 | 14 | 5 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 240 | 1 | 196 | 17 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [@elastic/kibana-localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 583 | 1 | 557 | 55 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 145 | 0 | 103 | 9 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 135 | 0 | 93 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 212 | 0 | 145 | 10 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer). | 13 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 55 | 0 | 23 | 2 | @@ -211,7 +212,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the vislib visualizations. These are the classical area/line/bar, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 1 | 0 | 1 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 52 | 0 | 50 | 5 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 837 | 12 | 807 | 19 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 835 | 12 | 804 | 19 | | watcher | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | ## Package Directory @@ -231,7 +232,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 23 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 0 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 21 | 0 | 0 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 22 | 0 | 1 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 18 | 0 | 2 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 34 | 0 | 34 | 8 | @@ -327,7 +328,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 26 | 6 | 26 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 13 | 0 | 13 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 454 | 1 | 179 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 59 | 0 | 53 | 8 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 58 | 0 | 52 | 9 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 44 | 0 | 43 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 2 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 3 | 0 | 3 | 0 | @@ -519,6 +520,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 8 | 0 | 0 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 2 | 0 | 1 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 29 | 0 | 29 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 18 | 0 | 18 | 0 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 31 | 1 | 24 | 1 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 78 | 0 | 76 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 55 | 1 | 50 | 0 | @@ -531,7 +533,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-performance-testing](https://github.com/orgs/elastic/teams/kibana-performance-testing) | - | 3 | 0 | 3 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 1 | 0 | -| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 171 | 0 | 28 | 0 | +| | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | - | 173 | 0 | 30 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 13 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 22 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 8 | 0 | 2 | 0 | @@ -559,7 +561,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 16 | 0 | 16 | 1 | | | [@elastic/security-detections-response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 116 | 0 | 113 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 0 | -| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 69 | 0 | 69 | 0 | +| | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 66 | 0 | 66 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | - | 2211 | 0 | 2211 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 20 | 0 | 18 | 1 | | | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 14 | 0 | 14 | 6 | @@ -584,7 +586,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 28 | 0 | 25 | 0 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 120 | 0 | 116 | 0 | | | [@elastic/security-detection-engine](https://github.com/orgs/elastic/teams/security-detection-engine) | - | 37 | 0 | 32 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 54 | 0 | 51 | 1 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 61 | 0 | 57 | 1 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 31 | 0 | 30 | 1 | | | [@elastic/appex-sharedux @elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 1 | 0 | 1 | 0 | | | [@elastic/appex-sharedux @elastic/platform-deployment-management @elastic/obs-ux-management-team](https://github.com/orgs/elastic/teams/appex-sharedux ) | - | 1 | 0 | 1 | 0 | @@ -636,16 +638,15 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 102 | 2 | 65 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 4 | 0 | 2 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 41 | 2 | 21 | 0 | -| | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 24 | 0 | 16 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 5 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 291 | 4 | 244 | 12 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 137 | 5 | 105 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 22 | 0 | 21 | 0 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 25 | 0 | 10 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 72 | 0 | 55 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 39 | 0 | 25 | 1 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 86 | 0 | 86 | 1 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 49 | 0 | 35 | 0 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 44 | 0 | 30 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 53 | 0 | 44 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 7 | 0 | 6 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the unified data table which can be integrated into apps | 109 | 0 | 49 | 1 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 23946072908f..0e9d35b25cd0 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-11-21 +date: 2023-11-27 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 53f9e92add84..eeab761c023c 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-11-21 +date: 2023-11-27 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 3b7404480742..278666ff3b00 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-11-21 +date: 2023-11-27 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 070cf277c3d2..634c37710558 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-11-21 +date: 2023-11-27 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 57e1d42fc664..9679e26df3a2 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-11-21 +date: 2023-11-27 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 93c8309731e9..fd1805c621db 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.devdocs.json b/api_docs/rule_registry.devdocs.json index 6a8f4d39d685..713a8f7b3680 100644 --- a/api_docs/rule_registry.devdocs.json +++ b/api_docs/rule_registry.devdocs.json @@ -626,7 +626,7 @@ "label": "getBrowserFields", "description": [], "signature": [ - "({ indices, metaFields, allowNoIndex, }: { indices: string[]; metaFields: string[]; allowNoIndex: boolean; }) => Promise<{ browserFields: ", + "({ featureIds, indices, metaFields, allowNoIndex, }: { featureIds: string[]; indices: string[]; metaFields: string[]; allowNoIndex: boolean; }) => Promise<{ browserFields: ", { "pluginId": "ruleRegistry", "scope": "common", @@ -653,12 +653,26 @@ "id": "def-server.AlertsClient.getBrowserFields.$1", "type": "Object", "tags": [], - "label": "{\n indices,\n metaFields,\n allowNoIndex,\n }", + "label": "{\n featureIds,\n indices,\n metaFields,\n allowNoIndex,\n }", "description": [], "path": "x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts", "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-server.AlertsClient.getBrowserFields.$1.featureIds", + "type": "Array", + "tags": [], + "label": "featureIds", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "ruleRegistry", "id": "def-server.AlertsClient.getBrowserFields.$1.indices", diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 82412e0806e8..136e7b4d6623 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 267 | 0 | 238 | 14 | +| 268 | 0 | 239 | 14 | ## Server diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index ba2aa31e6003..c232c1f59ff9 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-11-21 +date: 2023-11-27 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 60d9a14501a7..25b7fc0ffe06 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-11-21 +date: 2023-11-27 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 baa06ee207dd..2b40bbcff10b 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-11-21 +date: 2023-11-27 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 1005a80975a9..436da4a012c2 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-11-21 +date: 2023-11-27 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 aacaabfc7ded..8da791af3f6d 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-11-21 +date: 2023-11-27 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 80cef8add385..ef2f81249526 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-11-21 +date: 2023-11-27 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 0440633fabda..aaf4c2c0abf4 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-11-21 +date: 2023-11-27 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 6f704e31c384..3a8540526a6e 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-11-21 +date: 2023-11-27 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 9794c59a1229..3f505720983a 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-11-21 +date: 2023-11-27 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 71afdc49a95c..1c3cb004db99 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index 1fa3537631f7..add8a6b86116 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -114,7 +114,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/plugin.tsx", "deprecated": false, @@ -507,7 +507,7 @@ "\nExperimental flag needed to enable the link" ], "signature": [ - "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | undefined" + "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -587,7 +587,7 @@ "\nExperimental flag needed to disable the link. Opposite of experimentalKey" ], "signature": [ - "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | \"disableTimelineSaveTour\" | undefined" + "\"tGridEnabled\" | \"tGridEventRenderedViewEnabled\" | \"excludePoliciesInFilterEnabled\" | \"kubernetesEnabled\" | \"chartEmbeddablesEnabled\" | \"donutChartEmbeddablesEnabled\" | \"alertsPreviewChartEmbeddablesEnabled\" | \"previewTelemetryUrlEnabled\" | \"insightsRelatedAlertsByProcessAncestry\" | \"extendedRuleExecutionLoggingEnabled\" | \"socTrendsEnabled\" | \"responseActionsEnabled\" | \"endpointResponseActionsEnabled\" | \"responseActionUploadEnabled\" | \"alertsPageChartsEnabled\" | \"alertTypeEnabled\" | \"alertsPageFiltersEnabled\" | \"assistantModelEvaluation\" | \"newUserDetailsFlyout\" | \"riskScoringPersistence\" | \"riskScoringRoutesEnabled\" | \"esqlRulesDisabled\" | \"protectionUpdatesEnabled\" | undefined" ], "path": "x-pack/plugins/security_solution/public/common/links/types.ts", "deprecated": false, @@ -1820,7 +1820,7 @@ "label": "experimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/public/types.ts", "deprecated": false, @@ -1972,9 +1972,7 @@ "label": "setComponents", "description": [], "signature": [ - "(components: Partial>>) => void" + "(components: Partial<{ GetStarted: React.ComponentType<{}>; DashboardsLandingCallout: React.ComponentType<{}>; }>) => void" ], "path": "x-pack/plugins/security_solution/public/types.ts", "deprecated": false, @@ -1989,7 +1987,7 @@ "label": "components", "description": [], "signature": [ - "{ getStarted?: React.ComponentType<{}> | undefined; dashboardsLandingCallout?: React.ComponentType<{}> | undefined; }" + "{ GetStarted?: React.ComponentType<{}> | undefined; DashboardsLandingCallout?: React.ComponentType<{}> | undefined; }" ], "path": "x-pack/plugins/security_solution/public/contract_components.ts", "deprecated": false, @@ -2893,7 +2891,7 @@ "\nThe security solution generic experimental features" ], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/server/plugin_contract.ts", "deprecated": false, @@ -3039,7 +3037,7 @@ "label": "ExperimentalFeatures", "description": [], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, @@ -3088,7 +3086,7 @@ "\nA list of allowed values that can be used in `xpack.securitySolution.enableExperimental`.\nThis object is then used to validate and parse the value entered." ], "signature": [ - "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; readonly disableTimelineSaveTour: boolean; }" + "{ readonly tGridEnabled: boolean; readonly tGridEventRenderedViewEnabled: boolean; readonly excludePoliciesInFilterEnabled: boolean; readonly kubernetesEnabled: boolean; readonly chartEmbeddablesEnabled: boolean; readonly donutChartEmbeddablesEnabled: boolean; readonly alertsPreviewChartEmbeddablesEnabled: boolean; readonly previewTelemetryUrlEnabled: boolean; readonly insightsRelatedAlertsByProcessAncestry: boolean; readonly extendedRuleExecutionLoggingEnabled: boolean; readonly socTrendsEnabled: boolean; readonly responseActionsEnabled: boolean; readonly endpointResponseActionsEnabled: boolean; readonly responseActionUploadEnabled: boolean; readonly alertsPageChartsEnabled: boolean; readonly alertTypeEnabled: boolean; readonly alertsPageFiltersEnabled: boolean; readonly assistantModelEvaluation: boolean; readonly newUserDetailsFlyout: boolean; readonly riskScoringPersistence: boolean; readonly riskScoringRoutesEnabled: boolean; readonly esqlRulesDisabled: boolean; readonly protectionUpdatesEnabled: boolean; }" ], "path": "x-pack/plugins/security_solution/common/experimental_features.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 5450e147125a..1bbe48110236 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-solution](https://github.com/orgs/elastic/teams/secur | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 175 | 0 | 106 | 35 | +| 175 | 0 | 106 | 34 | ## Client diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 5bbfe83899ce..515e742f1e65 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-11-21 +date: 2023-11-27 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 9fe12f3dda99..396e8ab6cead 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-11-21 +date: 2023-11-27 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 3b5ace3dee12..31d679f16802 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-11-21 +date: 2023-11-27 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 87d382dc7db1..1f0ee0b16796 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-11-21 +date: 2023-11-27 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 6efa6ca0697b..58bdb2f07864 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-11-21 +date: 2023-11-27 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 5faff7bc9428..53ba1af905ce 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-11-21 +date: 2023-11-27 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 8481b3fb9a2c..41f032242b6b 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-11-21 +date: 2023-11-27 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 0159382bf9e2..5d2009933564 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-11-21 +date: 2023-11-27 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 e70cdce709a4..b05333b460a2 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-11-21 +date: 2023-11-27 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 792699a25fe9..a49b1539efb1 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-11-21 +date: 2023-11-27 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 b3ea1b2a30e1..78ff4dbc464f 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-11-21 +date: 2023-11-27 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 684fa40edd9d..63c2807ea2cf 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-11-21 +date: 2023-11-27 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 b8ad82872374..f1ebb599883c 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-11-21 +date: 2023-11-27 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 70e3e36ba45c..004e4a8f03ba 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-11-21 +date: 2023-11-27 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 fb2e7b5b1ab5..a6c298a01a20 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-11-21 +date: 2023-11-27 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 920b30581297..5f1190a1948b 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.devdocs.json b/api_docs/text_based_languages.devdocs.json index c44e1664a3fe..bfbd1ef629c7 100644 --- a/api_docs/text_based_languages.devdocs.json +++ b/api_docs/text_based_languages.devdocs.json @@ -69,7 +69,9 @@ "type": "CompoundType", "tags": [], "label": "query", - "description": [], + "description": [ + "The aggregate type query" + ], "signature": [ "{ sql: string; } | { esql: string; }" ], @@ -83,7 +85,9 @@ "type": "Function", "tags": [], "label": "onTextLangQueryChange", - "description": [], + "description": [ + "Callback running everytime the query changes" + ], "signature": [ "(query: ", { @@ -129,14 +133,47 @@ "type": "Function", "tags": [], "label": "onTextLangQuerySubmit", - "description": [], + "description": [ + "Callback running when the user submits the query" + ], "signature": [ - "() => void" + "(query?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.AggregateQuery", + "text": "AggregateQuery" + }, + " | undefined) => void" ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.onTextLangQuerySubmit.$1", + "type": "CompoundType", + "tags": [], + "label": "query", + "description": [], + "signature": [ + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.AggregateQuery", + "text": "AggregateQuery" + }, + " | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], "returnComment": [] }, { @@ -145,7 +182,9 @@ "type": "Function", "tags": [], "label": "expandCodeEditor", - "description": [], + "description": [ + "Can be used to expand/minimize the editor" + ], "signature": [ "(status: boolean) => void" ], @@ -177,7 +216,9 @@ "type": "boolean", "tags": [], "label": "isCodeEditorExpanded", - "description": [], + "description": [ + "If it is true, the editor initializes with height EDITOR_INITIAL_HEIGHT_EXPANDED" + ], "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", "deprecated": false, "trackAdoption": false @@ -188,7 +229,9 @@ "type": "CompoundType", "tags": [], "label": "detectTimestamp", - "description": [], + "description": [ + "If it is true, the editor displays the message @timestamp found\nThe text based queries are relying on adhoc dataviews which\ncan have an @timestamp timefield or nothing" + ], "signature": [ "boolean | undefined" ], @@ -202,7 +245,9 @@ "type": "Array", "tags": [], "label": "errors", - "description": [], + "description": [ + "Array of errors" + ], "signature": [ "Error[] | undefined" ], @@ -216,7 +261,9 @@ "type": "string", "tags": [], "label": "warning", - "description": [], + "description": [ + "Warning string as it comes from ES" + ], "signature": [ "string | undefined" ], @@ -230,7 +277,9 @@ "type": "CompoundType", "tags": [], "label": "isDisabled", - "description": [], + "description": [ + "Disables the editor" + ], "signature": [ "boolean | undefined" ], @@ -244,7 +293,9 @@ "type": "CompoundType", "tags": [], "label": "isDarkMode", - "description": [], + "description": [ + "Indicator if the editor is on dark mode" + ], "signature": [ "boolean | undefined" ], @@ -272,7 +323,9 @@ "type": "CompoundType", "tags": [], "label": "hideMinimizeButton", - "description": [], + "description": [ + "If true it hides the minimize button and the user can't return to the minimized version\nUseful when the application doesn't want to give this capability" + ], "signature": [ "boolean | undefined" ], @@ -286,7 +339,41 @@ "type": "CompoundType", "tags": [], "label": "hideRunQueryText", - "description": [], + "description": [ + "Hide the Run query information which appears on the footer" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.editorIsInline", + "type": "CompoundType", + "tags": [], + "label": "editorIsInline", + "description": [ + "This is used for applications (such as the inline editing flyout in dashboards)\nwhich want to add the editor without being part of the Unified search component\nIt renders a submit query button inside the editor" + ], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-text-based-editor/src/text_based_languages_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "textBasedLanguages", + "id": "def-public.TextBasedLanguagesEditorProps.disableSubmitAction", + "type": "CompoundType", + "tags": [], + "label": "disableSubmitAction", + "description": [ + "Disables the submit query action" + ], "signature": [ "boolean | undefined" ], diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 0cd5b475d919..93b6a02fd323 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 20 | 0 | 20 | 0 | +| 23 | 0 | 9 | 0 | ## Client diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index c0bb245253e8..28ef52f2b3ed 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-11-21 +date: 2023-11-27 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 cbbd6f3001ea..f8412716abd1 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-11-21 +date: 2023-11-27 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 b62fb485b542..c9fc1166bbfb 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-11-21 +date: 2023-11-27 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 0d0c10fe2d7d..c3a92c31fdea 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.devdocs.json b/api_docs/ui_actions.devdocs.json index fc3e6efa4a21..bf583998fc74 100644 --- a/api_docs/ui_actions.devdocs.json +++ b/api_docs/ui_actions.devdocs.json @@ -1634,71 +1634,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "uiActions", - "id": "def-public.CategorizeFieldContext", - "type": "Interface", - "tags": [], - "label": "CategorizeFieldContext", - "description": [], - "path": "src/plugins/ui_actions/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "uiActions", - "id": "def-public.CategorizeFieldContext.field", - "type": "Object", - "tags": [], - "label": "field", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataViewField", - "text": "DataViewField" - } - ], - "path": "src/plugins/ui_actions/public/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "uiActions", - "id": "def-public.CategorizeFieldContext.dataView", - "type": "Object", - "tags": [], - "label": "dataView", - "description": [], - "signature": [ - { - "pluginId": "dataViews", - "scope": "common", - "docId": "kibDataViewsPluginApi", - "section": "def-common.DataView", - "text": "DataView" - } - ], - "path": "src/plugins/ui_actions/public/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "uiActions", - "id": "def-public.CategorizeFieldContext.originatingApp", - "type": "string", - "tags": [], - "label": "originatingApp", - "description": [], - "path": "src/plugins/ui_actions/public/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "uiActions", "id": "def-public.Presentable", @@ -2300,21 +2235,6 @@ ], "enums": [], "misc": [ - { - "parentPluginId": "uiActions", - "id": "def-public.ACTION_CATEGORIZE_FIELD", - "type": "string", - "tags": [], - "label": "ACTION_CATEGORIZE_FIELD", - "description": [], - "signature": [ - "\"ACTION_CATEGORIZE_FIELD\"" - ], - "path": "src/plugins/ui_actions/public/types.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "uiActions", "id": "def-public.ACTION_VISUALIZE_FIELD", @@ -2384,21 +2304,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "uiActions", - "id": "def-public.CATEGORIZE_FIELD_TRIGGER", - "type": "string", - "tags": [], - "label": "CATEGORIZE_FIELD_TRIGGER", - "description": [], - "signature": [ - "\"CATEGORIZE_FIELD_TRIGGER\"" - ], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "uiActions", "id": "def-public.PresentableGrouping", @@ -2468,53 +2373,6 @@ } ], "objects": [ - { - "parentPluginId": "uiActions", - "id": "def-public.categorizeFieldTrigger", - "type": "Object", - "tags": [], - "label": "categorizeFieldTrigger", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "uiActions", - "id": "def-public.categorizeFieldTrigger.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "uiActions", - "id": "def-public.categorizeFieldTrigger.title", - "type": "string", - "tags": [], - "label": "title", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "uiActions", - "id": "def-public.categorizeFieldTrigger.description", - "type": "string", - "tags": [], - "label": "description", - "description": [], - "path": "packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "uiActions", "id": "def-public.rowClickTrigger", @@ -2665,15 +2523,15 @@ "label": "UiActionsSetup", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -2689,15 +2547,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; }" + ") => void; }" ], "path": "src/plugins/ui_actions/public/plugin.ts", "deprecated": false, @@ -2713,15 +2571,17 @@ "label": "UiActionsStart", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -2737,17 +2597,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 119d19b676dd..d6c31366d7c1 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 145 | 0 | 103 | 9 | +| 135 | 0 | 93 | 9 | ## Client diff --git a/api_docs/ui_actions_enhanced.devdocs.json b/api_docs/ui_actions_enhanced.devdocs.json index 774898421d86..83c71b1e3e65 100644 --- a/api_docs/ui_actions_enhanced.devdocs.json +++ b/api_docs/ui_actions_enhanced.devdocs.json @@ -3311,7 +3311,7 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + "{ readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -3327,7 +3327,7 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly getActionFactory: (actionFactoryId: string) => ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly getActionFactory: (actionFactoryId: string) => ", { "pluginId": "uiActionsEnhanced", "scope": "public", diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index b35189fa9f33..76b13b798938 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-11-21 +date: 2023-11-27 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 fcb42f4995b9..1246b5e56abc 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedDocViewer'] --- import unifiedDocViewerObj from './unified_doc_viewer.devdocs.json'; diff --git a/api_docs/unified_histogram.devdocs.json b/api_docs/unified_histogram.devdocs.json index 8cf2ef256b1a..23dd7f92c406 100644 --- a/api_docs/unified_histogram.devdocs.json +++ b/api_docs/unified_histogram.devdocs.json @@ -632,15 +632,17 @@ "label": "uiActions", "description": [], "signature": [ - "{ readonly addTriggerAction: (triggerId: string, action: ", + "{ readonly registerTrigger: (trigger: ", { - "pluginId": "uiActions", - "scope": "public", - "docId": "kibUiActionsPluginApi", - "section": "def-public.ActionDefinition", - "text": "ActionDefinition" + "pluginId": "@kbn/ui-actions-browser", + "scope": "common", + "docId": "kibKbnUiActionsBrowserPluginApi", + "section": "def-common.Trigger", + "text": "Trigger" }, - ") => void; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly registerAction: (definition: ", + ") => void; readonly getTrigger: (triggerId: string) => ", + "TriggerContract", + "; readonly registerAction: (definition: ", { "pluginId": "uiActions", "scope": "public", @@ -656,17 +658,15 @@ "section": "def-public.Action", "text": "Action" }, - "; readonly registerTrigger: (trigger: ", + "; readonly unregisterAction: (actionId: string) => void; readonly hasAction: (actionId: string) => boolean; readonly attachAction: (triggerId: string, actionId: string) => void; readonly detachAction: (triggerId: string, actionId: string) => void; readonly addTriggerAction: (triggerId: string, action: ", { - "pluginId": "@kbn/ui-actions-browser", - "scope": "common", - "docId": "kibKbnUiActionsBrowserPluginApi", - "section": "def-common.Trigger", - "text": "Trigger" + "pluginId": "uiActions", + "scope": "public", + "docId": "kibUiActionsPluginApi", + "section": "def-public.ActionDefinition", + "text": "ActionDefinition" }, - ") => void; readonly unregisterAction: (actionId: string) => void; readonly getTrigger: (triggerId: string) => ", - "TriggerContract", - "; readonly hasAction: (actionId: string) => boolean; readonly getAction: (id: string) => ", + ") => void; readonly getAction: (id: string) => ", { "pluginId": "uiActions", "scope": "public", diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 435cf6852c1f..7c645a70667f 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.devdocs.json b/api_docs/unified_search.devdocs.json index 09a1feea1cee..0d5e841aaada 100644 --- a/api_docs/unified_search.devdocs.json +++ b/api_docs/unified_search.devdocs.json @@ -635,7 +635,7 @@ }, "[] | undefined; refreshInterval?: number | undefined; iconType?: ", "IconType", - " | undefined; showQueryInput?: boolean | undefined; dataTestSubj?: string | undefined; showSaveQuery?: boolean | undefined; customSubmitButton?: React.ReactNode; dataViewPickerOverride?: React.ReactNode; screenTitle?: string | undefined; showQueryMenu?: boolean | undefined; showFilterBar?: boolean | undefined; showDatePicker?: boolean | undefined; showAutoRefreshOnly?: boolean | undefined; filtersForSuggestions?: ", + " | undefined; dataTestSubj?: string | undefined; showSaveQuery?: boolean | undefined; customSubmitButton?: React.ReactNode; dataViewPickerOverride?: React.ReactNode; screenTitle?: string | undefined; showQueryMenu?: boolean | undefined; showQueryInput?: boolean | undefined; showFilterBar?: boolean | undefined; showDatePicker?: boolean | undefined; showAutoRefreshOnly?: boolean | undefined; filtersForSuggestions?: ", { "pluginId": "@kbn/es-query", "scope": "common", diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index e25eb9f07c79..2869a6b8e168 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-11-21 +date: 2023-11-27 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 80770fd0906a..0b520a3fe5c5 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-11-21 +date: 2023-11-27 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 eb3d2fe74b6b..d99b9e86d173 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-11-21 +date: 2023-11-27 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 0adcc2b86110..ba3ddcdd5308 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-11-21 +date: 2023-11-27 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 64a089c595d7..1977c74caf10 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-11-21 +date: 2023-11-27 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 e4620d3b85b5..d49961b39c67 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-11-21 +date: 2023-11-27 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 b053b0378685..3748ba1e8e0a 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-11-21 +date: 2023-11-27 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 750deacc01e9..b24468ee76b3 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-11-21 +date: 2023-11-27 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 57fa856dc54d..b207c7e4e454 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-11-21 +date: 2023-11-27 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 0f0badc0c556..83df4f3c2785 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-11-21 +date: 2023-11-27 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 d7550681770c..45b970eddf04 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-11-21 +date: 2023-11-27 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 c0159abeeaa6..8b17df03d5d5 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-11-21 +date: 2023-11-27 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 bf4e8cbb0c90..9ebfe3bce002 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-11-21 +date: 2023-11-27 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 215b50874052..50871bd26054 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-11-21 +date: 2023-11-27 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 9c92d4649afd..6b93e6b7fd3a 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-11-21 +date: 2023-11-27 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 c1e88b69f7ac..092dc3f0f4c0 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index b9e6229c9486..a10f69575cdb 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -4423,22 +4423,16 @@ "children": [ { "parentPluginId": "visualizations", - "id": "def-public.VisTypeAlias.aliasPath", - "type": "string", - "tags": [], - "label": "aliasPath", - "description": [], - "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.VisTypeAlias.aliasApp", - "type": "string", + "id": "def-public.VisTypeAlias.alias", + "type": "Object", "tags": [], - "label": "aliasApp", - "description": [], + "label": "alias", + "description": [ + "\nProvide `alias` when your visualization has a dedicated app for creation.\nTODO: Provide a generic callback to create visualizations inline." + ], + "signature": [ + "{ app: string; path: string; } | undefined" + ], "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", "deprecated": false, "trackAdoption": false @@ -5874,31 +5868,6 @@ "deprecated": false, "trackAdoption": false, "children": [ - { - "parentPluginId": "visualizations", - "id": "def-public.VisualizationListItem.editUrl", - "type": "string", - "tags": [], - "label": "editUrl", - "description": [], - "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "visualizations", - "id": "def-public.VisualizationListItem.editApp", - "type": "string", - "tags": [], - "label": "editApp", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "visualizations", "id": "def-public.VisualizationListItem.error", @@ -6055,6 +6024,20 @@ "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "visualizations", + "id": "def-public.VisualizationListItem.editor", + "type": "CompoundType", + "tags": [], + "label": "editor", + "description": [], + "signature": [ + "{ editUrl: string; editApp?: string | undefined; } | { onEdit: (savedObjectId: string) => Promise; }" + ], + "path": "src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 678ee4d217f2..dbea80fe3bee 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-11-21 +date: 2023-11-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 837 | 12 | 807 | 19 | +| 835 | 12 | 804 | 19 | ## Client diff --git a/catalog-info.yaml b/catalog-info.yaml index 96b4c146590a..dbdc1dc24aa0 100644 --- a/catalog-info.yaml +++ b/catalog-info.yaml @@ -54,19 +54,9 @@ spec: provider_settings: trigger_mode: none teams: - kibana-release-operators: - access_level: MANAGE_BUILD_AND_READ kibana-operations: access_level: MANAGE_BUILD_AND_READ - appex-qa: - access_level: BUILD_AND_READ - security-engineering-productivity: - access_level: BUILD_AND_READ - fleet: - access_level: BUILD_AND_READ - kibana-tech-leads: - access_level: BUILD_AND_READ - kibana-core: + kibana-release-operators: access_level: BUILD_AND_READ cloud-tooling: access_level: BUILD_AND_READ diff --git a/package.json b/package.json index b2ef6e211107..5e43d8bb910c 100644 --- a/package.json +++ b/package.json @@ -555,6 +555,7 @@ "@kbn/ml-runtime-field-utils": "link:x-pack/packages/ml/runtime_field_utils", "@kbn/ml-string-hash": "link:x-pack/packages/ml/string_hash", "@kbn/ml-trained-models-utils": "link:x-pack/packages/ml/trained_models_utils", + "@kbn/ml-ui-actions": "link:x-pack/packages/ml/ui_actions", "@kbn/ml-url-state": "link:x-pack/packages/ml/url_state", "@kbn/monaco": "link:packages/kbn-monaco", "@kbn/monitoring-collection-plugin": "link:x-pack/plugins/monitoring_collection", @@ -749,7 +750,6 @@ "@kbn/status-plugin-a-plugin": "link:test/server_integration/plugins/status_plugin_a", "@kbn/status-plugin-b-plugin": "link:test/server_integration/plugins/status_plugin_b", "@kbn/std": "link:packages/kbn-std", - "@kbn/subscription-tracking": "link:packages/kbn-subscription-tracking", "@kbn/synthetics-plugin": "link:x-pack/plugins/synthetics", "@kbn/task-manager-fixture-plugin": "link:x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture", "@kbn/task-manager-performance-plugin": "link:x-pack/test/plugin_api_perf/plugins/task_manager_performance", @@ -1237,6 +1237,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/mock-idp-plugin": "link:packages/kbn-mock-idp-plugin", "@kbn/openapi-generator": "link:packages/kbn-openapi-generator", "@kbn/optimizer": "link:packages/kbn-optimizer", "@kbn/optimizer-webpack-helpers": "link:packages/kbn-optimizer-webpack-helpers", diff --git a/packages/content-management/table_list_view_table/src/components/item_details.tsx b/packages/content-management/table_list_view_table/src/components/item_details.tsx index 0b2f52b21690..6c14c9c52021 100644 --- a/packages/content-management/table_list_view_table/src/components/item_details.tsx +++ b/packages/content-management/table_list_view_table/src/components/item_details.tsx @@ -57,7 +57,7 @@ export function ItemDetails({ ); const onClickTitleHandler = useMemo(() => { - if (!onClickTitle) { + if (!onClickTitle || getDetailViewLink?.(item)) { return undefined; } @@ -65,7 +65,7 @@ export function ItemDetails({ e.preventDefault(); onClickTitle(item); }) as React.MouseEventHandler; - }, [item, onClickTitle]); + }, [item, onClickTitle, getDetailViewLink]); const renderTitle = useCallback(() => { const href = getDetailViewLink ? getDetailViewLink(item) : undefined; @@ -79,7 +79,7 @@ export function ItemDetails({ {/* eslint-disable-next-line @elastic/eui/href-or-on-click */} diff --git a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx index ccf6ef791d8d..f7de8935ea94 100644 --- a/packages/content-management/table_list_view_table/src/table_list_view_table.tsx +++ b/packages/content-management/table_list_view_table/src/table_list_view_table.tsx @@ -289,12 +289,6 @@ function TableListViewTableComp({ ); } - if (getDetailViewLink && onClickTitle) { - throw new Error( - `[TableListView] Either "getDetailViewLink" or "onClickTitle" can be provided. Not both.` - ); - } - if (contentEditor.isReadonly === false && contentEditor.onSave === undefined) { throw new Error( `[TableListView] A value for [contentEditor.onSave()] must be provided when [contentEditor.isReadonly] is false.` diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx index 30fe35be0b55..80f108c8be78 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx @@ -62,6 +62,17 @@ const getHeaderCss = ({ size }: EuiThemeComputed) => ({ top: 2px; `, }, + leftHeaderSection: css` + // needed to enable breadcrumbs truncation + min-width: 0; + flex-shrink: 1; + `, + breadcrumbsSectionItem: css` + min-width: 0; // needed to enable breadcrumbs truncation + `, + redirectAppLinksContainer: css` + min-width: 0; // needed to enable breadcrumbs truncation + `, }); type HeaderCss = ReturnType; @@ -181,7 +192,7 @@ export const ProjectHeader = ({
    - + {children} @@ -196,8 +207,11 @@ export const ProjectHeader = ({ /> - - + + diff --git a/packages/kbn-subscription-tracking/src/helpers.ts b/packages/core/http/core-http-server-internal/src/http_server.test.mocks.ts similarity index 56% rename from packages/kbn-subscription-tracking/src/helpers.ts rename to packages/core/http/core-http-server-internal/src/http_server.test.mocks.ts index 251c0d1c0411..6b0eadee96f3 100644 --- a/packages/kbn-subscription-tracking/src/helpers.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.test.mocks.ts @@ -6,9 +6,13 @@ * Side Public License, v 1. */ -import type { SubscriptionContextData } from '../types'; +export const setTlsConfigMock = jest.fn(); -const sourceStringRegEx = /^(\w[\w\-_]*)__(\w[\w\-_]*)$/; -export function isValidContext(context: SubscriptionContextData): boolean { - return context.feature.length > 0 && sourceStringRegEx.test(context.source); -} +jest.doMock('@kbn/server-http-tools', () => { + const actual = jest.requireActual('@kbn/server-http-tools'); + return { + ...actual, + setTlsConfig: setTlsConfigMock, + createServer: jest.fn(actual.createServer), + }; +}); diff --git a/packages/core/http/core-http-server-internal/src/http_server.test.ts b/packages/core/http/core-http-server-internal/src/http_server.test.ts index f70b035c5f22..d50156df94ed 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.test.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.test.ts @@ -6,20 +6,12 @@ * Side Public License, v 1. */ -jest.mock('@kbn/server-http-tools', () => { - const module = jest.requireActual('@kbn/server-http-tools'); - return { - ...module, - createServer: jest.fn(module.createServer), - }; -}); - +import { setTlsConfigMock } from './http_server.test.mocks'; import { Server } from 'http'; import { rm, mkdtemp, readFile, writeFile } from 'fs/promises'; import supertest from 'supertest'; import { omit } from 'lodash'; import { join } from 'path'; - import { ByteSizeValue, schema } from '@kbn/config-schema'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import type { @@ -37,7 +29,7 @@ import { HttpServer } from './http_server'; import { Readable } from 'stream'; import { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; import moment from 'moment'; -import { of } from 'rxjs'; +import { of, Observable, BehaviorSubject } from 'rxjs'; const routerOptions: RouterOptions = { isDev: false, @@ -52,8 +44,12 @@ const cookieOptions = { }; let server: HttpServer; + let config: HttpConfig; +let config$: Observable; + let configWithSSL: HttpConfig; +let configWithSSL$: Observable; const loggingService = loggingSystemMock.create(); const logger = loggingService.get(); @@ -85,6 +81,7 @@ beforeEach(() => { cdn: {}, shutdownTimeout: moment.duration(500, 'ms'), } as any; + config$ = of(config); configWithSSL = { ...config, @@ -97,6 +94,7 @@ beforeEach(() => { redirectHttpFromPort: config.port + 1, }, } as HttpConfig; + configWithSSL$ = of(configWithSSL); server = new HttpServer(loggingService, 'tests', of(config.shutdownTimeout)); }); @@ -109,7 +107,7 @@ afterEach(async () => { test('log listening address after started', async () => { expect(server.isListening()).toBe(false); - await server.setup(config); + await server.setup({ config$ }); await server.start(); expect(server.isListening()).toBe(true); @@ -125,7 +123,7 @@ test('log listening address after started', async () => { test('log listening address after started when configured with BasePath and rewriteBasePath = false', async () => { expect(server.isListening()).toBe(false); - await server.setup({ ...config, basePath: '/bar', rewriteBasePath: false }); + await server.setup({ config$: of({ ...config, basePath: '/bar', rewriteBasePath: false }) }); await server.start(); expect(server.isListening()).toBe(true); @@ -141,7 +139,7 @@ test('log listening address after started when configured with BasePath and rewr test('log listening address after started when configured with BasePath and rewriteBasePath = true', async () => { expect(server.isListening()).toBe(false); - await server.setup({ ...config, basePath: '/bar', rewriteBasePath: true }); + await server.setup({ config$: of({ ...config, basePath: '/bar', rewriteBasePath: true }) }); await server.start(); expect(server.isListening()).toBe(true); @@ -157,7 +155,7 @@ test('log listening address after started when configured with BasePath and rewr test('does not allow router registration after server is listening', async () => { expect(server.isListening()).toBe(false); - const { registerRouter } = await server.setup(config); + const { registerRouter } = await server.setup({ config$ }); const router1 = new Router('/foo', logger, enhanceWithContext, routerOptions); expect(() => registerRouter(router1)).not.toThrowError(); @@ -175,7 +173,7 @@ test('does not allow router registration after server is listening', async () => test('allows router registration after server is listening via `registerRouterAfterListening`', async () => { expect(server.isListening()).toBe(false); - const { registerRouterAfterListening } = await server.setup(config); + const { registerRouterAfterListening } = await server.setup({ config$ }); const router1 = new Router('/foo', logger, enhanceWithContext, routerOptions); expect(() => registerRouterAfterListening(router1)).not.toThrowError(); @@ -205,7 +203,7 @@ test('valid params', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -235,7 +233,7 @@ test('invalid params', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -270,7 +268,7 @@ test('valid query', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -300,7 +298,7 @@ test('invalid query', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -335,7 +333,7 @@ test('valid body', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -373,7 +371,7 @@ test('valid body with validate function', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -416,7 +414,7 @@ test('not inline validation - specifying params', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -459,7 +457,7 @@ test('not inline validation - specifying validation handler', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -509,7 +507,7 @@ test('not inline handler - KibanaRequest', async () => { handler ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -558,7 +556,7 @@ test('not inline handler - RequestHandler', async () => { handler ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -592,7 +590,7 @@ test('invalid body', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -627,7 +625,7 @@ test('handles putting', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -658,7 +656,7 @@ test('handles deleting', async () => { } ); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); registerRouter(router); await server.start(); @@ -688,7 +686,9 @@ describe('with `basepath: /bar` and `rewriteBasePath: false`', () => { res.ok({ body: 'value:/foo' }) ); - const { registerRouter, server: innerServer } = await server.setup(configWithBasePath); + const { registerRouter, server: innerServer } = await server.setup({ + config$: of(configWithBasePath), + }); registerRouter(router); await server.start(); @@ -743,7 +743,9 @@ describe('with `basepath: /bar` and `rewriteBasePath: true`', () => { res.ok({ body: 'value:/foo' }) ); - const { registerRouter, server: innerServer } = await server.setup(configWithBasePath); + const { registerRouter, server: innerServer } = await server.setup({ + config$: of(configWithBasePath), + }); registerRouter(router); await server.start(); @@ -790,7 +792,7 @@ test('with defined `redirectHttpFromPort`', async () => { const router = new Router('/', logger, enhanceWithContext, routerOptions); router.get({ path: '/', validate: false }, (context, req, res) => res.ok({ body: 'value:/' })); - const { registerRouter } = await server.setup(configWithSSL); + const { registerRouter } = await server.setup({ config$: configWithSSL$ }); registerRouter(router); await server.start(); @@ -801,7 +803,7 @@ test('returns server and connection options on start', async () => { ...config, port: 12345, }; - const { server: innerServer } = await server.setup(configWithPort); + const { server: innerServer } = await server.setup({ config$: of(configWithPort) }); expect(innerServer).toBeDefined(); expect(innerServer).toBe((server as any).server); @@ -815,7 +817,7 @@ test('throws an error if starts without set up', async () => { test('allows attaching metadata to attach meta-data tag strings to a route', async () => { const tags = ['my:tag']; - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.get({ path: '/with-tags', validate: false, options: { tags } }, (context, req, res) => @@ -834,7 +836,7 @@ test('allows attaching metadata to attach meta-data tag strings to a route', asy test('allows declaring route access to flag a route as public or internal', async () => { const access = 'internal'; - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.get({ path: '/with-access', validate: false, options: { access } }, (context, req, res) => @@ -852,7 +854,7 @@ test('allows declaring route access to flag a route as public or internal', asyn }); test(`sets access flag to 'internal' if not defined`, async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.get({ path: '/internal/foo', validate: false }, (context, req, res) => @@ -883,7 +885,7 @@ test(`sets access flag to 'internal' if not defined`, async () => { }); test('exposes route details of incoming request to a route handler', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.get({ path: '/', validate: false }, (context, req, res) => res.ok({ body: req.route })); @@ -907,7 +909,9 @@ test('exposes route details of incoming request to a route handler', async () => describe('conditional compression', () => { async function setupServer(innerConfig: HttpConfig) { - const { registerRouter, server: innerServer } = await server.setup(innerConfig); + const { registerRouter, server: innerServer } = await server.setup({ + config$: of(innerConfig), + }); const router = new Router('', logger, enhanceWithContext, routerOptions); // we need the large body here so that compression would normally be used const largeRequest = { @@ -1012,8 +1016,10 @@ describe('conditional compression', () => { describe('response headers', () => { test('allows to configure "keep-alive" header', async () => { const { registerRouter, server: innerServer } = await server.setup({ - ...config, - keepaliveTimeout: 100_000, + config$: of({ + ...config, + keepaliveTimeout: 100_000, + }), }); const router = new Router('', logger, enhanceWithContext, routerOptions); @@ -1031,7 +1037,7 @@ describe('response headers', () => { }); test('default headers', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.get({ path: '/', validate: false }, (context, req, res) => res.ok({ body: req.route })); @@ -1053,7 +1059,7 @@ describe('response headers', () => { }); test('exposes route details of incoming request to a route handler (POST + payload options)', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1093,7 +1099,7 @@ test('exposes route details of incoming request to a route handler (POST + paylo describe('body options', () => { test('should reject the request because the Content-Type in the request is not valid', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1115,7 +1121,7 @@ describe('body options', () => { }); test('should reject the request because the payload is too large', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1137,7 +1143,7 @@ describe('body options', () => { }); test('should not parse the content in the request', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1166,7 +1172,7 @@ describe('body options', () => { describe('timeout options', () => { describe('payload timeout', () => { test('POST routes set the payload timeout', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1200,7 +1206,7 @@ describe('timeout options', () => { }); test('DELETE routes set the payload timeout', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.delete( @@ -1233,7 +1239,7 @@ describe('timeout options', () => { }); test('PUT routes set the payload timeout and automatically adjusts the idle socket timeout', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.put( @@ -1266,7 +1272,7 @@ describe('timeout options', () => { }); test('PATCH routes set the payload timeout and automatically adjusts the idle socket timeout', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.patch( @@ -1302,8 +1308,10 @@ describe('timeout options', () => { describe('idleSocket timeout', () => { test('uses server socket timeout when not specified in the route', async () => { const { registerRouter, server: innerServer } = await server.setup({ - ...config, - socketTimeout: 11000, + config$: of({ + ...config, + socketTimeout: 11000, + }), }); const router = new Router('', logger, enhanceWithContext, routerOptions); @@ -1335,8 +1343,10 @@ describe('timeout options', () => { test('sets the socket timeout when specified in the route', async () => { const { registerRouter, server: innerServer } = await server.setup({ - ...config, - socketTimeout: 11000, + config$: of({ + ...config, + socketTimeout: 11000, + }), }); const router = new Router('', logger, enhanceWithContext, routerOptions); @@ -1368,7 +1378,7 @@ describe('timeout options', () => { }); test('idleSocket timeout can be smaller than the payload timeout', async () => { - const { registerRouter } = await server.setup(config); + const { registerRouter } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.post( @@ -1395,7 +1405,7 @@ describe('timeout options', () => { }); test('should return a stream in the body', async () => { - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$ }); const router = new Router('', logger, enhanceWithContext, routerOptions); router.put( @@ -1421,8 +1431,10 @@ test('should return a stream in the body', async () => { test('closes sockets on timeout', async () => { const { registerRouter, server: innerServer } = await server.setup({ - ...config, - socketTimeout: 1000, + config$: of({ + ...config, + socketTimeout: 1000, + }), }); const router = new Router('', logger, enhanceWithContext, routerOptions); @@ -1446,14 +1458,14 @@ test('closes sockets on timeout', async () => { describe('setup contract', () => { describe('#createSessionStorage', () => { test('creates session storage factory', async () => { - const { createCookieSessionStorageFactory } = await server.setup(config); + const { createCookieSessionStorageFactory } = await server.setup({ config$ }); const sessionStorageFactory = await createCookieSessionStorageFactory(cookieOptions); expect(sessionStorageFactory.asScoped).toBeDefined(); }); test('creates session storage factory only once', async () => { - const { createCookieSessionStorageFactory } = await server.setup(config); + const { createCookieSessionStorageFactory } = await server.setup({ config$ }); const create = async () => await createCookieSessionStorageFactory(cookieOptions); await create(); @@ -1461,7 +1473,7 @@ describe('setup contract', () => { }); test('does not throw if called after stop', async () => { - const { createCookieSessionStorageFactory } = await server.setup(config); + const { createCookieSessionStorageFactory } = await server.setup({ config$ }); await server.stop(); expect(() => { createCookieSessionStorageFactory(cookieOptions); @@ -1471,7 +1483,7 @@ describe('setup contract', () => { describe('#getServerInfo', () => { test('returns correct information', async () => { - let { getServerInfo } = await server.setup(config); + let { getServerInfo } = await server.setup({ config$ }); expect(getServerInfo()).toEqual({ hostname: '127.0.0.1', @@ -1481,10 +1493,12 @@ describe('setup contract', () => { }); ({ getServerInfo } = await server.setup({ - ...config, - port: 12345, - name: 'custom-name', - host: 'localhost', + config$: of({ + ...config, + port: 12345, + name: 'custom-name', + host: 'localhost', + }), })); expect(getServerInfo()).toEqual({ @@ -1496,7 +1510,7 @@ describe('setup contract', () => { }); test('returns correct protocol when ssl is enabled', async () => { - const { getServerInfo } = await server.setup(configWithSSL); + const { getServerInfo } = await server.setup({ config$: configWithSSL$ }); expect(getServerInfo().protocol).toEqual('https'); }); @@ -1517,7 +1531,7 @@ describe('setup contract', () => { }); test('registers routes with expected options', async () => { - const { registerStaticDir } = await server.setup(config); + const { registerStaticDir } = await server.setup({ config$ }); expect(createServer).toHaveBeenCalledTimes(1); const [{ value: myServer }] = (createServer as jest.Mock).mock.results; jest.spyOn(myServer, 'route'); @@ -1540,7 +1554,7 @@ describe('setup contract', () => { }); test('does not throw if called after stop', async () => { - const { registerStaticDir } = await server.setup(config); + const { registerStaticDir } = await server.setup({ config$ }); await server.stop(); expect(() => { registerStaticDir('/path1/{path*}', '/path/to/resource'); @@ -1548,7 +1562,7 @@ describe('setup contract', () => { }); test('returns correct headers for static assets', async () => { - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', assetFolder); @@ -1562,7 +1576,7 @@ describe('setup contract', () => { }); test('returns compressed version if present', async () => { - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', assetFolder); @@ -1578,7 +1592,7 @@ describe('setup contract', () => { }); test('returns uncompressed version if compressed asset is not available', async () => { - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', assetFolder); @@ -1594,7 +1608,7 @@ describe('setup contract', () => { }); test('returns a 304 if etag value matches', async () => { - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', assetFolder); @@ -1613,7 +1627,7 @@ describe('setup contract', () => { }); test('serves content if etag values does not match', async () => { - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', assetFolder); @@ -1628,7 +1642,7 @@ describe('setup contract', () => { test('dynamically updates depending on the content of the file', async () => { const tempFile = join(tempDir, 'some_file.json'); - const { registerStaticDir, server: innerServer } = await server.setup(config); + const { registerStaticDir, server: innerServer } = await server.setup({ config$ }); registerStaticDir('/static/{path*}', tempDir); await server.start(); @@ -1655,7 +1669,7 @@ describe('setup contract', () => { describe('#registerOnPreRouting', () => { test('does not throw if called after stop', async () => { - const { registerOnPreRouting } = await server.setup(config); + const { registerOnPreRouting } = await server.setup({ config$ }); await server.stop(); expect(() => { registerOnPreRouting((req, res) => res.unauthorized()); @@ -1665,7 +1679,7 @@ describe('setup contract', () => { describe('#registerOnPreAuth', () => { test('does not throw if called after stop', async () => { - const { registerOnPreAuth } = await server.setup(config); + const { registerOnPreAuth } = await server.setup({ config$ }); await server.stop(); expect(() => { registerOnPreAuth((req, res) => res.unauthorized()); @@ -1675,7 +1689,7 @@ describe('setup contract', () => { describe('#registerOnPostAuth', () => { test('does not throw if called after stop', async () => { - const { registerOnPostAuth } = await server.setup(config); + const { registerOnPostAuth } = await server.setup({ config$ }); await server.stop(); expect(() => { registerOnPostAuth((req, res) => res.unauthorized()); @@ -1685,7 +1699,7 @@ describe('setup contract', () => { describe('#registerOnPreResponse', () => { test('does not throw if called after stop', async () => { - const { registerOnPreResponse } = await server.setup(config); + const { registerOnPreResponse } = await server.setup({ config$ }); await server.stop(); expect(() => { registerOnPreResponse((req, res, t) => t.next()); @@ -1695,7 +1709,7 @@ describe('setup contract', () => { describe('#registerAuth', () => { test('does not throw if called after stop', async () => { - const { registerAuth } = await server.setup(config); + const { registerAuth } = await server.setup({ config$ }); await server.stop(); expect(() => { registerAuth((req, res) => res.unauthorized()); @@ -1703,3 +1717,52 @@ describe('setup contract', () => { }); }); }); + +describe('configuration change', () => { + it('logs a warning in case of incompatible config change', async () => { + const configSubject = new BehaviorSubject(configWithSSL); + + await server.setup({ config$: configSubject }); + await server.start(); + + const nextConfig = { + ...configWithSSL, + ssl: { + ...configWithSSL.ssl, + getSecureOptions: () => 0, + enabled: false, + }, + } as HttpConfig; + + configSubject.next(nextConfig); + + expect(loggingService.get().warn).toHaveBeenCalledWith( + 'Incompatible TLS config change detected - TLS cannot be toggled without a full server reboot.' + ); + }); + + it('calls setTlsConfig and logs an info message when config changes', async () => { + const configSubject = new BehaviorSubject(configWithSSL); + + const { server: innerServer } = await server.setup({ config$: configSubject }); + await server.start(); + + const nextConfig = { + ...configWithSSL, + ssl: { + ...configWithSSL.ssl, + isEqualTo: () => false, + getSecureOptions: () => 0, + }, + } as HttpConfig; + + configSubject.next(nextConfig); + + expect(setTlsConfigMock).toHaveBeenCalledTimes(1); + expect(setTlsConfigMock).toHaveBeenCalledWith(innerServer, nextConfig.ssl); + + expect(loggingService.get().info).toHaveBeenCalledWith( + 'TLS configuration change detected - reloading TLS configuration.' + ); + }); +}); diff --git a/packages/core/http/core-http-server-internal/src/http_server.ts b/packages/core/http/core-http-server-internal/src/http_server.ts index fb776f5d29eb..1361c64bb67c 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.ts @@ -14,12 +14,13 @@ import { createServer, getListenerOptions, getServerOptions, + setTlsConfig, getRequestId, } from '@kbn/server-http-tools'; import type { Duration } from 'moment'; -import { firstValueFrom, Observable } from 'rxjs'; -import { take } from 'rxjs/operators'; +import { firstValueFrom, Observable, Subscription } from 'rxjs'; +import { take, pairwise } from 'rxjs/operators'; import apm from 'elastic-apm-node'; // @ts-expect-error no type definition import Brok from 'brok'; @@ -160,9 +161,15 @@ export type LifecycleRegistrar = Pick< | 'registerOnPreResponse' >; +export interface HttpServerSetupOptions { + config$: Observable; + executionContext?: InternalExecutionContextSetup; +} + export class HttpServer { private server?: Server; private config?: HttpConfig; + private subscriptions: Subscription[] = []; private registeredRouters = new Set(); private authRegistered = false; private cookieSessionStorageCreated = false; @@ -209,13 +216,16 @@ export class HttpServer { } } - public async setup( - config: HttpConfig, - executionContext?: InternalExecutionContextSetup - ): Promise { + public async setup({ + config$, + executionContext, + }: HttpServerSetupOptions): Promise { + const config = await firstValueFrom(config$); + this.config = config; + const serverOptions = getServerOptions(config); const listenerOptions = getListenerOptions(config); - this.config = config; + this.server = createServer(serverOptions, listenerOptions); await this.server.register([HapiStaticFiles]); if (config.compression.brotli.enabled) { @@ -227,6 +237,29 @@ export class HttpServer { }); } + // only hot-reloading TLS config - don't need to subscribe if TLS is initially disabled, + // given we can't hot-switch from/to enabled/disabled. + if (config.ssl.enabled) { + const configSubscription = config$ + .pipe(pairwise()) + .subscribe(([{ ssl: prevSslConfig }, { ssl: newSslConfig }]) => { + if (prevSslConfig.enabled !== newSslConfig.enabled) { + this.log.warn( + 'Incompatible TLS config change detected - TLS cannot be toggled without a full server reboot.' + ); + return; + } + + const sameConfig = newSslConfig.isEqualTo(prevSslConfig); + + if (!sameConfig) { + this.log.info('TLS configuration change detected - reloading TLS configuration.'); + setTlsConfig(this.server!, newSslConfig); + } + }); + this.subscriptions.push(configSubscription); + } + // It's important to have setupRequestStateAssignment call the very first, otherwise context passing will be broken. // That's the only reason why context initialization exists in this method. this.setupRequestStateAssignment(config, executionContext); diff --git a/packages/core/http/core-http-server-internal/src/http_service.ts b/packages/core/http/core-http-server-internal/src/http_service.ts index 99d286b26f83..b09e7e84fef2 100644 --- a/packages/core/http/core-http-server-internal/src/http_service.ts +++ b/packages/core/http/core-http-server-internal/src/http_service.ts @@ -71,7 +71,7 @@ export class HttpService this.env = env; this.log = logger.get('http'); this.config$ = combineLatest([ - configService.atPath(httpConfig.path), + configService.atPath(httpConfig.path, { ignoreUnchanged: false }), configService.atPath(cspConfig.path), configService.atPath(externalUrlConfig.path), ]).pipe(map(([http, csp, externalUrl]) => new HttpConfig(http, csp, externalUrl))); @@ -85,7 +85,9 @@ export class HttpService this.log.debug('setting up preboot server'); const config = await firstValueFrom(this.config$); - const prebootSetup = await this.prebootServer.setup(config); + const prebootSetup = await this.prebootServer.setup({ + config$: this.config$, + }); prebootSetup.server.route({ path: '/{p*}', method: '*', @@ -157,10 +159,10 @@ export class HttpService const config = await firstValueFrom(this.config$); - const { registerRouter, ...serverContract } = await this.httpServer.setup( - config, - deps.executionContext - ); + const { registerRouter, ...serverContract } = await this.httpServer.setup({ + config$: this.config$, + executionContext: deps.executionContext, + }); registerCoreHandlers(serverContract, config, this.env, this.log); diff --git a/packages/core/logging/core-logging-server-internal/src/__snapshots__/logging_system.test.ts.snap b/packages/core/logging/core-logging-server-internal/src/__snapshots__/logging_system.test.ts.snap index 01ffd79b0b87..d283fc1400c7 100644 --- a/packages/core/logging/core-logging-server-internal/src/__snapshots__/logging_system.test.ts.snap +++ b/packages/core/logging/core-logging-server-internal/src/__snapshots__/logging_system.test.ts.snap @@ -25,6 +25,7 @@ Object { "message": "buffered trace message", "process": Object { "pid": Any, + "uptime": 10, }, } `; @@ -42,6 +43,7 @@ Object { "message": "buffered info message", "process": Object { "pid": Any, + "uptime": 10, }, "some": "value", } @@ -60,6 +62,7 @@ Object { "message": "buffered fatal message", "process": Object { "pid": Any, + "uptime": 10, }, } `; @@ -77,6 +80,7 @@ Object { "message": "buffered info message", "process": Object { "pid": Any, + "uptime": 10, }, "some": "value", } @@ -95,6 +99,7 @@ Object { "message": "some new info message", "process": Object { "pid": Any, + "uptime": 10, }, } `; diff --git a/packages/core/logging/core-logging-server-internal/src/layouts/__snapshots__/json_layout.test.ts.snap b/packages/core/logging/core-logging-server-internal/src/layouts/__snapshots__/json_layout.test.ts.snap index 0809dbffce67..da1c1b4c4f8b 100644 --- a/packages/core/logging/core-logging-server-internal/src/layouts/__snapshots__/json_layout.test.ts.snap +++ b/packages/core/logging/core-logging-server-internal/src/layouts/__snapshots__/json_layout.test.ts.snap @@ -15,6 +15,7 @@ Object { "message": "message-1", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -29,6 +30,7 @@ Object { "message": "message-2", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -43,6 +45,7 @@ Object { "message": "message-3", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -57,6 +60,7 @@ Object { "message": "message-4", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -71,6 +75,7 @@ Object { "message": "message-5", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -85,6 +90,7 @@ Object { "message": "message-6", "process": Object { "pid": 5355, + "uptime": 10, }, } `; @@ -99,6 +105,7 @@ Object { "message": "message-6", "process": Object { "pid": 5355, + "uptime": 10, }, "span": Object { "id": "spanId-1", diff --git a/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.test.ts b/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.test.ts index 60b415b1b2a2..8d16ce8a576f 100644 --- a/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.test.ts @@ -10,6 +10,8 @@ import { EcsVersion } from '@kbn/ecs'; import { LogLevel, LogRecord } from '@kbn/logging'; import { JsonLayout } from './json_layout'; +jest.spyOn(process, 'uptime').mockReturnValue(10); + const timestamp = new Date(Date.UTC(2012, 1, 1, 14, 30, 22, 11)); const records: LogRecord[] = [ { @@ -121,6 +123,7 @@ test('`format()` correctly formats record with meta-data', () => { }, process: { pid: 5355, + uptime: 10, }, }); }); @@ -169,6 +172,7 @@ test('`format()` correctly formats error record with meta-data', () => { }, process: { pid: 5355, + uptime: 10, }, }); }); @@ -202,6 +206,7 @@ test('format() meta can merge override logs', () => { }, process: { pid: 3, + uptime: 10, }, }); }); @@ -232,6 +237,7 @@ test('format() meta can not override message', () => { }, process: { pid: 3, + uptime: 10, }, }); }); @@ -262,6 +268,7 @@ test('format() meta can not override ecs version', () => { }, process: { pid: 3, + uptime: 10, }, }); }); @@ -295,6 +302,7 @@ test('format() meta can not override logger or level', () => { }, process: { pid: 3, + uptime: 10, }, }); }); @@ -325,6 +333,7 @@ test('format() meta can not override timestamp', () => { }, process: { pid: 3, + uptime: 10, }, }); }); @@ -359,6 +368,7 @@ test('format() meta can not override tracing properties', () => { }, process: { pid: 3, + uptime: 10, }, span: { id: 'span_override' }, trace: { id: 'trace_override' }, @@ -404,6 +414,7 @@ test('format() meta.toJSON() is used if own property', () => { }, process: { pid: 3, + uptime: 10, }, server: { address: 'localhost', @@ -448,6 +459,7 @@ test('format() meta.toJSON() is used if present on prototype', () => { }, process: { pid: 3, + uptime: 10, }, foo: 'bar', }); diff --git a/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.ts b/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.ts index 43b906fa8407..59921b0f4b7f 100644 --- a/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.ts +++ b/packages/core/logging/core-logging-server-internal/src/layouts/json_layout.ts @@ -53,6 +53,7 @@ export class JsonLayout implements Layout { }, process: { pid: record.pid, + uptime: process.uptime(), }, span: spanId ? { id: spanId } : undefined, trace: traceId ? { id: traceId } : undefined, diff --git a/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts b/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts index 81eb539a618f..76fe93d1e614 100644 --- a/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts +++ b/packages/core/logging/core-logging-server-internal/src/logging_system.test.ts @@ -23,6 +23,7 @@ let system: LoggingSystem; beforeEach(() => { mockConsoleLog = jest.spyOn(global.console, 'log').mockReturnValue(undefined); jest.spyOn(global, 'Date').mockImplementation(() => timestamp); + jest.spyOn(process, 'uptime').mockReturnValue(10); system = new LoggingSystem(); }); diff --git a/packages/core/saved-objects/docs/openapi/bundled.json b/packages/core/saved-objects/docs/openapi/bundled.json index dd6b95fa959b..4382ee9b62d9 100644 --- a/packages/core/saved-objects/docs/openapi/bundled.json +++ b/packages/core/saved-objects/docs/openapi/bundled.json @@ -757,7 +757,7 @@ "post": { "summary": "Resolve errors from the Import objects API.", "operationId": "resolveImportErrors", - "description": "To resolve errors, you can: \n\n* Retry certain saved objects\n* Overwrite specific saved objects\n* Change references to different saved objects\n\nThis functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.\n", + "description": "To resolve errors, you can:\n\n* Retry certain saved objects\n* Overwrite specific saved objects\n* Change references to different saved objects\n\nThis functionality is in technical preview and may be changed or removed in a future release. Elastic will work to fix any issues, but features in technical preview are not subject to the support SLA of official GA features.\n", "tags": [ "saved objects" ], @@ -1210,7 +1210,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "examples": { diff --git a/packages/core/saved-objects/docs/openapi/bundled.yaml b/packages/core/saved-objects/docs/openapi/bundled.yaml index 3e07633a5107..a12e326ccdbe 100644 --- a/packages/core/saved-objects/docs/openapi/bundled.yaml +++ b/packages/core/saved-objects/docs/openapi/bundled.yaml @@ -208,7 +208,7 @@ paths: responses: '200': description: | - Indicates a successful call. NOTE: This HTTP response code indicates that the bulk operation succeeded. Errors pertaining to individual objects will be returned in the response body. + Indicates a successful call. NOTE: This HTTP response code indicates that the bulk operation succeeded. Errors pertaining to individual objects will be returned in the response body. content: application/json: schema: @@ -239,7 +239,7 @@ paths: responses: '200': description: | - Indicates a successful call. NOTE: This HTTP response code indicates that the bulk operation succeeded. Errors pertaining to individual objects will be returned in the response body. + Indicates a successful call. NOTE: This HTTP response code indicates that the bulk operation succeeded. Errors pertaining to individual objects will be returned in the response body. content: application/json: schema: @@ -798,7 +798,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' examples: key_rotation_response: summary: Encryption key rotation using default parameters. diff --git a/packages/core/saved-objects/docs/openapi/entrypoint.yaml b/packages/core/saved-objects/docs/openapi/entrypoint.yaml index cfb8a93210a5..b4e58a6ef217 100644 --- a/packages/core/saved-objects/docs/openapi/entrypoint.yaml +++ b/packages/core/saved-objects/docs/openapi/entrypoint.yaml @@ -49,7 +49,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - - apiKeyAuth: [] \ No newline at end of file + - apiKeyAuth: [] diff --git a/packages/kbn-config/src/config_service.test.ts b/packages/kbn-config/src/config_service.test.ts index 434534f6d888..b03d407c2fcc 100644 --- a/packages/kbn-config/src/config_service.test.ts +++ b/packages/kbn-config/src/config_service.test.ts @@ -131,6 +131,23 @@ test("does not push new configs when reloading if config at path hasn't changed" expect(valuesReceived).toEqual(['value']); }); +test("does push new configs when reloading when config at path hasn't changed if ignoreUnchanged is false", async () => { + const rawConfig$ = new BehaviorSubject>({ key: 'value' }); + const rawConfigProvider = createRawConfigServiceMock({ rawConfig$ }); + + const configService = new ConfigService(rawConfigProvider, defaultEnv, logger); + await configService.setSchema('key', schema.string()); + + const valuesReceived: any[] = []; + configService.atPath('key', { ignoreUnchanged: false }).subscribe((value) => { + valuesReceived.push(value); + }); + + rawConfig$.next({ key: 'value' }); + + expect(valuesReceived).toEqual(['value', 'value']); +}); + test('pushes new config when reloading and config at path has changed', async () => { const rawConfig$ = new BehaviorSubject>({ key: 'value' }); const rawConfigProvider = createRawConfigServiceMock({ rawConfig$ }); diff --git a/packages/kbn-config/src/config_service.ts b/packages/kbn-config/src/config_service.ts index 0026876f70b4..e1c4ccfb55fb 100644 --- a/packages/kbn-config/src/config_service.ts +++ b/packages/kbn-config/src/config_service.ts @@ -10,7 +10,7 @@ import type { PublicMethodsOf } from '@kbn/utility-types'; import { SchemaTypeError, Type, ValidationError } from '@kbn/config-schema'; import { cloneDeep, isEqual, merge } from 'lodash'; import { set } from '@kbn/safer-lodash-set'; -import { BehaviorSubject, combineLatest, firstValueFrom, Observable } from 'rxjs'; +import { BehaviorSubject, combineLatest, firstValueFrom, Observable, identity } from 'rxjs'; import { distinctUntilChanged, first, map, shareReplay, tap } from 'rxjs/operators'; import { Logger, LoggerFactory } from '@kbn/logging'; import { getDocLinks, DocLinks } from '@kbn/doc-links'; @@ -159,9 +159,13 @@ export class ConfigService { * against its registered schema. * * @param path - The path to the desired subset of the config. + * @param ignoreUnchanged - If true (default), will not emit if the config at path did not change. */ - public atPath(path: ConfigPath) { - return this.getValidatedConfigAtPath$(path) as Observable; + public atPath( + path: ConfigPath, + { ignoreUnchanged = true }: { ignoreUnchanged?: boolean } = {} + ) { + return this.getValidatedConfigAtPath$(path, { ignoreUnchanged }) as Observable; } /** @@ -310,10 +314,13 @@ export class ConfigService { ); } - private getValidatedConfigAtPath$(path: ConfigPath) { + private getValidatedConfigAtPath$( + path: ConfigPath, + { ignoreUnchanged = true }: { ignoreUnchanged?: boolean } = {} + ) { return this.config$.pipe( map((config) => config.get(path)), - distinctUntilChanged(isEqual), + ignoreUnchanged ? distinctUntilChanged(isEqual) : identity, map((config) => this.validateAtPath(path, config)) ); } diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts index afc8252e7e13..ffc6a0de28f2 100644 --- a/packages/kbn-doc-links/src/get_doc_links.ts +++ b/packages/kbn-doc-links/src/get_doc_links.ts @@ -770,6 +770,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => { installAndUninstallIntegrationAssets: `${FLEET_DOCS}install-uninstall-integration-assets.html`, elasticAgentInputConfiguration: `${FLEET_DOCS}elastic-agent-input-configuration.html`, policySecrets: `${FLEET_DOCS}agent-policy.html#agent-policy-secret-values`, + remoteESOoutput: `${FLEET_DOCS}monitor-elastic-agent.html#external-elasticsearch-monitoring`, }, ecs: { guide: `${ELASTIC_WEBSITE_URL}guide/en/ecs/current/index.html`, diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts index 5e4202dd7fa4..7afa37539eb8 100644 --- a/packages/kbn-doc-links/src/types.ts +++ b/packages/kbn-doc-links/src/types.ts @@ -528,6 +528,7 @@ export interface DocLinks { installAndUninstallIntegrationAssets: string; elasticAgentInputConfiguration: string; policySecrets: string; + remoteESOoutput: string; }>; readonly ecs: { readonly guide: string; diff --git a/packages/kbn-es/src/cli_commands/serverless.ts b/packages/kbn-es/src/cli_commands/serverless.ts index 87a573a8810d..0743cf2e7b5b 100644 --- a/packages/kbn-es/src/cli_commands/serverless.ts +++ b/packages/kbn-es/src/cli_commands/serverless.ts @@ -38,6 +38,7 @@ export const serverless: Command = { --host Publish ES docker container on additional host IP --port The port to bind to on 127.0.0.1 [default: ${DEFAULT_PORT}] --ssl Enable HTTP SSL on the ES cluster + --kibanaUrl Fully qualified URL where Kibana is hosted (including base path). [default: https://localhost:5601/] --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 --resources Overrides resources under ES 'config/' directory, which are by default @@ -73,7 +74,7 @@ export const serverless: Command = { files: 'F', }, - string: ['tag', 'image', 'basePath', 'resources', 'host'], + string: ['tag', 'image', 'basePath', 'resources', 'host', 'kibanaUrl'], boolean: ['clean', 'ssl', 'kill', 'background', 'skipTeardown', 'waitForReady'], default: defaults, diff --git a/packages/kbn-es/src/paths.ts b/packages/kbn-es/src/paths.ts index d9b4be41aa15..4da444857338 100644 --- a/packages/kbn-es/src/paths.ts +++ b/packages/kbn-es/src/paths.ts @@ -8,6 +8,7 @@ import Os from 'os'; import { resolve } from 'path'; +import { REPO_ROOT } from '@kbn/repo-info'; function maybeUseBat(bin: string) { return Os.platform().startsWith('win') ? `${bin}.bat` : bin; @@ -51,6 +52,8 @@ export const SERVERLESS_SECRETS_SSL_PATH = resolve( export const SERVERLESS_JWKS_PATH = resolve(__dirname, './serverless_resources/jwks.json'); +export const SERVERLESS_IDP_METADATA_PATH = resolve(REPO_ROOT, '.es', 'idp_metadata.xml'); + export const SERVERLESS_RESOURCES_PATHS = [ SERVERLESS_OPERATOR_USERS_PATH, SERVERLESS_ROLE_MAPPING_PATH, diff --git a/packages/kbn-es/src/serverless_resources/roles.yml b/packages/kbn-es/src/serverless_resources/roles.yml index 5f968ece56e3..a98652d5b931 100644 --- a/packages/kbn-es/src/serverless_resources/roles.yml +++ b/packages/kbn-es/src/serverless_resources/roles.yml @@ -210,6 +210,7 @@ t3_analyst: privileges: - read - write + - maintenance - names: - .lists* - .items* @@ -263,12 +264,16 @@ threat_intelligence_analyst: - endgame-* - filebeat-* - logs-* - - .lists* - - .items* - packetbeat-* - winlogbeat-* privileges: - read + - names: + - .lists* + - .items* + privileges: + - read + - write - names: - .alerts-security* - .siem-signals-* @@ -287,8 +292,7 @@ threat_intelligence_analyst: - application: "kibana-.kibana" privileges: - feature_ml.read - - feature_siem.read - - feature_siem.read_alerts + - feature_siem.all - feature_siem.endpoint_list_read - feature_siem.blocklist_all - feature_securitySolutionCases.all @@ -573,12 +577,12 @@ endpoint_operations_analyst: privileges: - read - write + - maintenance applications: - application: "kibana-.kibana" privileges: - feature_ml.read - feature_siem.all - - feature_siem.read_alerts - feature_siem.policy_management_all - feature_siem.endpoint_list_all - feature_siem.trusted_applications_all @@ -623,11 +627,15 @@ endpoint_policy_manager: - logs-* - packetbeat-* - winlogbeat-* + - risk-score.risk-score-* + privileges: + - read + - names: - .lists* - .items* - - risk-score.risk-score-* privileges: - read + - write - names: - .alerts-security* - .siem-signals-* diff --git a/packages/kbn-es/src/serverless_resources/security_roles.json b/packages/kbn-es/src/serverless_resources/security_roles.json index 5ac286a41c16..c4a06751e19b 100644 --- a/packages/kbn-es/src/serverless_resources/security_roles.json +++ b/packages/kbn-es/src/serverless_resources/security_roles.json @@ -107,7 +107,7 @@ }, { "names": [".alerts-security*", ".siem-signals-*"], - "privileges": ["read", "write"] + "privileges": ["read", "write", "maintenance"] }, { "names": [".lists*", ".items*"], diff --git a/packages/kbn-es/src/utils/docker.test.ts b/packages/kbn-es/src/utils/docker.test.ts index 2d71a4e628e1..b574447a2050 100644 --- a/packages/kbn-es/src/utils/docker.test.ts +++ b/packages/kbn-es/src/utils/docker.test.ts @@ -32,15 +32,17 @@ import { ServerlessOptions, } from './docker'; import { ToolingLog, ToolingLogCollectingWriter } from '@kbn/tooling-log'; -import { ES_P12_PATH } from '@kbn/dev-utils'; +import { CA_CERT_PATH, ES_P12_PATH } from '@kbn/dev-utils'; import { SERVERLESS_CONFIG_PATH, SERVERLESS_RESOURCES_PATHS, SERVERLESS_SECRETS_PATH, SERVERLESS_JWKS_PATH, + SERVERLESS_IDP_METADATA_PATH, } from '../paths'; import * as waitClusterUtil from './wait_until_cluster_ready'; import * as waitForSecurityIndexUtil from './wait_for_security_index'; +import * as mockIdpPluginUtil from '@kbn/mock-idp-plugin/common'; jest.mock('execa'); const execa = jest.requireMock('execa'); @@ -58,6 +60,8 @@ jest.mock('./wait_for_security_index', () => ({ waitForSecurityIndex: jest.fn(), })); +jest.mock('@kbn/mock-idp-plugin/common'); + const log = new ToolingLog(); const logWriter = new ToolingLogCollectingWriter(); log.setWriters([logWriter]); @@ -69,6 +73,8 @@ const serverlessObjectStorePath = `${baseEsPath}/${serverlessDir}`; const waitUntilClusterReadyMock = jest.spyOn(waitClusterUtil, 'waitUntilClusterReady'); const waitForSecurityIndexMock = jest.spyOn(waitForSecurityIndexUtil, 'waitForSecurityIndex'); +const ensureSAMLRoleMappingMock = jest.spyOn(mockIdpPluginUtil, 'ensureSAMLRoleMapping'); +const createMockIdpMetadataMock = jest.spyOn(mockIdpPluginUtil, 'createMockIdpMetadata'); beforeEach(() => { jest.resetAllMocks(); @@ -423,6 +429,66 @@ describe('resolveEsArgs()', () => { ] `); }); + + test('should add SAML realm args when kibanaUrl and SSL are passed', () => { + const esArgs = resolveEsArgs([], { + ssl: true, + kibanaUrl: 'https://localhost:5601/', + }); + + expect(esArgs).toHaveLength(26); + expect(esArgs).toMatchInlineSnapshot(` + Array [ + "--env", + "xpack.security.http.ssl.enabled=true", + "--env", + "xpack.security.http.ssl.keystore.path=/usr/share/elasticsearch/config/certs/elasticsearch.p12", + "--env", + "xpack.security.http.ssl.verification_mode=certificate", + "--env", + "xpack.security.authc.realms.saml.mock-idp.order=0", + "--env", + "xpack.security.authc.realms.saml.mock-idp.idp.metadata.path=/usr/share/elasticsearch/config/secrets/idp_metadata.xml", + "--env", + "xpack.security.authc.realms.saml.mock-idp.idp.entity_id=urn:mock-idp", + "--env", + "xpack.security.authc.realms.saml.mock-idp.sp.entity_id=https://localhost:5601", + "--env", + "xpack.security.authc.realms.saml.mock-idp.sp.acs=https://localhost:5601/api/security/saml/callback", + "--env", + "xpack.security.authc.realms.saml.mock-idp.sp.logout=https://localhost:5601/logout", + "--env", + "xpack.security.authc.realms.saml.mock-idp.attributes.principal=http://saml.elastic-cloud.com/attributes/principal", + "--env", + "xpack.security.authc.realms.saml.mock-idp.attributes.groups=http://saml.elastic-cloud.com/attributes/roles", + "--env", + "xpack.security.authc.realms.saml.mock-idp.attributes.name=http://saml.elastic-cloud.com/attributes/email", + "--env", + "xpack.security.authc.realms.saml.mock-idp.attributes.mail=http://saml.elastic-cloud.com/attributes/name", + ] + `); + }); + + test('should not add SAML realm args when security is disabled', () => { + const esArgs = resolveEsArgs([['xpack.security.enabled', 'false']], { + ssl: true, + kibanaUrl: 'https://localhost:5601/', + }); + + expect(esArgs).toHaveLength(8); + expect(esArgs).toMatchInlineSnapshot(` + Array [ + "--env", + "xpack.security.enabled=false", + "--env", + "xpack.security.http.ssl.enabled=true", + "--env", + "xpack.security.http.ssl.keystore.path=/usr/share/elasticsearch/config/certs/elasticsearch.p12", + "--env", + "xpack.security.http.ssl.verification_mode=certificate", + ] + `); + }); }); describe('setupServerlessVolumes()', () => { @@ -463,21 +529,29 @@ describe('setupServerlessVolumes()', () => { expect(existsSync(`${serverlessObjectStorePath}/cluster_state/lease`)).toBe(false); }); - test('should add SSL volumes when ssl is passed', async () => { + test('should add SSL and IDP metadata volumes when ssl and kibanaUrl are passed', async () => { mockFs(existingObjectStore); + createMockIdpMetadataMock.mockResolvedValue(''); - const volumeCmd = await setupServerlessVolumes(log, { basePath: baseEsPath, ssl: true }); + const volumeCmd = await setupServerlessVolumes(log, { + basePath: baseEsPath, + ssl: true, + kibanaUrl: 'https://localhost:5603/', + }); + + expect(createMockIdpMetadataMock).toHaveBeenCalledTimes(1); + expect(createMockIdpMetadataMock).toHaveBeenCalledWith('https://localhost:5603/'); const requiredPaths = [ `${baseEsPath}:/objectstore:z`, + SERVERLESS_IDP_METADATA_PATH, ES_P12_PATH, ...SERVERLESS_RESOURCES_PATHS, ]; const pathsNotIncludedInCmd = requiredPaths.filter( (path) => !volumeCmd.some((cmd) => cmd.includes(path)) ); - - expect(volumeCmd).toHaveLength(20); + expect(volumeCmd).toHaveLength(22); expect(pathsNotIncludedInCmd).toEqual([]); }); @@ -543,6 +617,7 @@ describe('runServerlessEsNode()', () => { describe('runServerlessCluster()', () => { test('should start 3 serverless nodes', async () => { + waitUntilClusterReadyMock.mockResolvedValue(); mockFs({ [baseEsPath]: {}, }); @@ -567,7 +642,27 @@ describe('runServerlessCluster()', () => { expect(waitUntilClusterReadyMock.mock.calls[0][0].readyTimeout).toEqual(undefined); }); + test(`should create SAML role mapping when ssl and kibanaUrl are passed`, async () => { + waitUntilClusterReadyMock.mockResolvedValue(); + mockFs({ + [CA_CERT_PATH]: '', + [baseEsPath]: {}, + }); + execa.mockImplementation(() => Promise.resolve({ stdout: '' })); + createMockIdpMetadataMock.mockResolvedValue(''); + + await runServerlessCluster(log, { + basePath: baseEsPath, + waitForReady: true, + ssl: true, + kibanaUrl: 'https://localhost:5601/', + }); + + expect(ensureSAMLRoleMappingMock).toHaveBeenCalledTimes(1); + }); + test(`should wait for the security index`, async () => { + waitUntilClusterReadyMock.mockResolvedValue(); waitForSecurityIndexMock.mockResolvedValue(); mockFs({ [baseEsPath]: {}, @@ -580,6 +675,7 @@ describe('runServerlessCluster()', () => { }); test(`should not wait for the security index when security is disabled`, async () => { + waitUntilClusterReadyMock.mockResolvedValue(); mockFs({ [baseEsPath]: {}, }); diff --git a/packages/kbn-es/src/utils/docker.ts b/packages/kbn-es/src/utils/docker.ts index 1c89339e1a56..73e5e1fc7728 100644 --- a/packages/kbn-es/src/utils/docker.ts +++ b/packages/kbn-es/src/utils/docker.ts @@ -14,12 +14,17 @@ import { Client, ClientOptions, HttpConnection } from '@elastic/elasticsearch'; import { ToolingLog } from '@kbn/tooling-log'; import { kibanaPackageJson as pkg, REPO_ROOT } from '@kbn/repo-info'; +import { CA_CERT_PATH, ES_P12_PASSWORD, ES_P12_PATH } from '@kbn/dev-utils'; import { - CA_CERT_PATH, - ES_P12_PASSWORD, - ES_P12_PATH, - kibanaDevServiceAccount, -} from '@kbn/dev-utils'; + MOCK_IDP_REALM_NAME, + MOCK_IDP_ENTITY_ID, + MOCK_IDP_ATTRIBUTE_PRINCIPAL, + MOCK_IDP_ATTRIBUTE_ROLES, + MOCK_IDP_ATTRIBUTE_EMAIL, + MOCK_IDP_ATTRIBUTE_NAME, + ensureSAMLRoleMapping, + createMockIdpMetadata, +} from '@kbn/mock-idp-plugin/common'; import { waitForSecurityIndex } from './wait_for_security_index'; import { createCliError } from '../errors'; @@ -28,6 +33,7 @@ import { SERVERLESS_RESOURCES_PATHS, SERVERLESS_SECRETS_PATH, SERVERLESS_JWKS_PATH, + SERVERLESS_IDP_METADATA_PATH, SERVERLESS_CONFIG_PATH, SERVERLESS_FILES_PATH, SERVERLESS_SECRETS_SSL_PATH, @@ -69,6 +75,8 @@ export interface ServerlessOptions extends EsClusterExecOptions, BaseOptions { background?: boolean; /** Wait for the ES cluster to be ready to serve requests */ waitForReady?: boolean; + /** Fully qualified URL where Kibana is hosted (including base path) */ + kibanaUrl?: string; /** * Resource file(s) to overwrite * (see list of files that can be overwritten under `packages/kbn-es/src/serverless_resources/users`) @@ -460,6 +468,54 @@ export function resolveEsArgs( esArgs.set('ELASTIC_PASSWORD', password); } + // Configure mock identify provider (ES only supports SAML when running in SSL mode) + if ( + ssl && + 'kibanaUrl' in options && + options.kibanaUrl && + esArgs.get('xpack.security.enabled') !== 'false' + ) { + const trimTrailingSlash = (url: string) => (url.endsWith('/') ? url.slice(0, -1) : url); + + esArgs.set(`xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.order`, '0'); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.idp.metadata.path`, + `${SERVERLESS_CONFIG_PATH}secrets/idp_metadata.xml` + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.idp.entity_id`, + MOCK_IDP_ENTITY_ID + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.sp.entity_id`, + trimTrailingSlash(options.kibanaUrl) + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.sp.acs`, + `${trimTrailingSlash(options.kibanaUrl)}/api/security/saml/callback` + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.sp.logout`, + `${trimTrailingSlash(options.kibanaUrl)}/logout` + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.principal`, + MOCK_IDP_ATTRIBUTE_PRINCIPAL + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.groups`, + MOCK_IDP_ATTRIBUTE_ROLES + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.name`, + MOCK_IDP_ATTRIBUTE_EMAIL + ); + esArgs.set( + `xpack.security.authc.realms.saml.${MOCK_IDP_REALM_NAME}.attributes.mail`, + MOCK_IDP_ATTRIBUTE_NAME + ); + } + return Array.from(esArgs).flatMap((e) => ['--env', e.join('=')]); } @@ -480,7 +536,7 @@ export function getDockerFileMountPath(hostPath: string) { * Setup local volumes for Serverless ES */ export async function setupServerlessVolumes(log: ToolingLog, options: ServerlessOptions) { - const { basePath, clean, ssl, files, resources } = options; + const { basePath, clean, ssl, kibanaUrl, files, resources } = options; const objectStorePath = resolve(basePath, 'stateless'); log.info(chalk.bold(`Checking for local serverless ES object store at ${objectStorePath}`)); @@ -551,6 +607,16 @@ export async function setupServerlessVolumes(log: ToolingLog, options: Serverles ); } + // Create and add meta data for mock identity provider + if (ssl && kibanaUrl) { + const metadata = await createMockIdpMetadata(kibanaUrl); + await Fsp.writeFile(SERVERLESS_IDP_METADATA_PATH, metadata); + volumeCmds.push( + '--volume', + `${SERVERLESS_IDP_METADATA_PATH}:${SERVERLESS_CONFIG_PATH}secrets/idp_metadata.xml:z` + ); + } + volumeCmds.push( ...getESp12Volume(), ...serverlessResources, @@ -559,7 +625,6 @@ export async function setupServerlessVolumes(log: ToolingLog, options: Serverles `${ ssl ? SERVERLESS_SECRETS_SSL_PATH : SERVERLESS_SECRETS_PATH }:${SERVERLESS_CONFIG_PATH}secrets/secrets.json:z`, - '--volume', `${SERVERLESS_JWKS_PATH}:${SERVERLESS_CONFIG_PATH}secrets/jwks.json:z` ); @@ -661,33 +726,52 @@ export async function runServerlessCluster(log: ToolingLog, options: ServerlessO process.on('SIGINT', () => teardownServerlessClusterSync(log, options)); } + const esNodeUrl = `${options.ssl ? 'https' : 'http'}://${portCmd[1].substring( + 0, + portCmd[1].lastIndexOf(':') + )}`; + + const client = getESClient({ + node: esNodeUrl, + auth: { + username: ELASTIC_SERVERLESS_SUPERUSER, + password: ELASTIC_SERVERLESS_SUPERUSER_PASSWORD, + }, + ...(options.ssl + ? { + tls: { + ca: [fs.readFileSync(CA_CERT_PATH)], + // NOTE: Even though we've added ca into the tls options, we are using 127.0.0.1 instead of localhost + // for the ip which is not validated. As such we are getting the error + // Hostname/IP does not match certificate's altnames: IP: 127.0.0.1 is not in the cert's list: + // To work around that we are overriding the function checkServerIdentity too + checkServerIdentity: () => { + return undefined; + }, + }, + } + : {}), + }); + + const readyPromise = waitUntilClusterReady({ client, expectedStatus: 'green', log }).then( + async () => { + if (!options.ssl || !options.kibanaUrl) { + return; + } + + await ensureSAMLRoleMapping(client); + + log.success( + `Created role mapping for mock identity provider. You can now login using ${chalk.bold.cyan( + MOCK_IDP_REALM_NAME + )} realm` + ); + } + ); + if (options.waitForReady) { log.info('Waiting until ES is ready to serve requests...'); - - const esNodeUrl = `${options.ssl ? 'https' : 'http'}://${portCmd[1].substring( - 0, - portCmd[1].lastIndexOf(':') - )}`; - - const client = getESClient({ - node: esNodeUrl, - auth: { bearer: kibanaDevServiceAccount.token }, - ...(options.ssl - ? { - tls: { - ca: [fs.readFileSync(CA_CERT_PATH)], - // NOTE: Even though we've added ca into the tls options, we are using 127.0.0.1 instead of localhost - // for the ip which is not validated. As such we are getting the error - // Hostname/IP does not match certificate's altnames: IP: 127.0.0.1 is not in the cert's list: - // To work around that we are overriding the function checkServerIdentity too - checkServerIdentity: () => { - return undefined; - }, - }, - } - : {}), - }); - await waitUntilClusterReady({ client, expectedStatus: 'green', log }); + await readyPromise; if (!options.esArgs || !options.esArgs.includes('xpack.security.enabled=false')) { // If security is not disabled, make sure the security index exists before running the test to avoid flakiness await waitForSecurityIndex({ client, log }); diff --git a/packages/kbn-es/tsconfig.json b/packages/kbn-es/tsconfig.json index 75059c2ef69c..b40ca3382556 100644 --- a/packages/kbn-es/tsconfig.json +++ b/packages/kbn-es/tsconfig.json @@ -3,13 +3,20 @@ "compilerOptions": { "outDir": "target/types" }, - "include": ["**/*.ts", "**/*.js", "**/*.json"], - "exclude": ["target/**/*"], + "include": [ + "**/*.ts", + "**/*.js", + "**/*.json" + ], + "exclude": [ + "target/**/*" + ], "kbn_references": [ "@kbn/tooling-log", "@kbn/dev-utils", "@kbn/dev-proc-runner", "@kbn/ci-stats-reporter", + "@kbn/mock-idp-plugin", "@kbn/jest-serializers", "@kbn/repo-info" ] diff --git a/packages/kbn-eslint-plugin-i18n/README.mdx b/packages/kbn-eslint-plugin-i18n/README.mdx index 174457477e81..6b836eb8bb52 100644 --- a/packages/kbn-eslint-plugin-i18n/README.mdx +++ b/packages/kbn-eslint-plugin-i18n/README.mdx @@ -6,22 +6,88 @@ description: Custom ESLint rules to support translations in the Kibana repositor tags: ['kibana', 'dev', 'contributor', 'operations', 'eslint', 'i18n'] --- -`@kbn/eslint-plugin-i18n` is an ESLint plugin providing custom rules for validating JSXCode in the Kibana repo to make sure they are translated. +# Summary -Note: At the moment these rules only work for apps that are inside `/x-pack/plugins`. -If you want to enable this rule on code that is outside of this path, adjust `/helpers/get_i18n_identifier_from_file_path.ts`. +`@kbn/eslint-plugin-i18n` is an ESLint plugin providing custom ESLint rules to help validating code in the Kibana repo in the area of translations. + +The aim of this package is to help engineers type less and have a nicer experience. + +If a rule does not behave as you expect or you have an idea of how these rules can be improved, please reach out to the Observability Knowledge Team or the Kibana Operations team. + +# Rules ## `@kbn/i18n/strings_should_be_translated_with_i18n` -This rule warns engineers to translate their strings by using i18n.translate from the '@kbn/i18n' package. It provides an autofix that takes into account the context of the translatable string in the JSX tree to generate a translation ID. -It kicks in on JSXText elements and specific JSXAttributes (`label` and `aria-label`) which expect a translated value. +This rule warns engineers to translate their strings by using `i18n.translate` from the `@kbn/i18n` package. + +It provides an autofix that takes into account the context of the translatable string in the JSX tree to generate a translation ID. + +This rule kicks in on: + +- JSXText elements; +- specific JSXAttributes (`label` and `aria-label`) which expect a translated value. + +### Example + +This code: + +``` +// Filename: /x-pack/plugins/observability/public/my_component.tsx + +import React from 'react'; +import { EuiText } from '@elastic/eui'; + +function MyComponent() { + return ( + You know, for search + ) +} +``` + +will be autofixed with: + +``` +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiText } from '@elastic/eui'; + +function MyComponent() { + return ( + + {i18n.translate('xpack.observability.myComponent.textLabel', { defaultMessage: 'You know, for search' } )} + + ) +} +``` + +If `i18n` has not been imported yet, the autofix will automatically add the import statement as well. + +### Exemptions and exceptions + +A JSXText element or JSXAttribute `label` or `aria-label` of which the value is: + +- wrapped in a `EuiCode` or `EuiBetaBadge` component, +- made up of non alpha characters such as `!@#$%^&*(){}` or numbers, +- wrapped in three backticks, + +are exempt from this rule. + +If this rule kicks in on a string value that you don't like, you can escape it by wrapping the string inside a JSXExpression: `{'my escaped value'}`. + +--- ## `@kbn/i18n/strings_should_be_translated_with_formatted_message` -This rule warns engineers to translate their strings by using `` from the '@kbn/i18n-react' package. It provides an autofix that takes into account the context of the translatable string in the JSX tree and to generate a translation ID. -It kicks in on JSXText elements and specific JSXAttributes (`label` and `aria-label`) which expect a translated value. +This rule warns engineers to translate their strings by using `` from the `@kbn/i18n-react` package. + +It provides an autofix that takes into account the context of the translatable string in the JSX tree and to generate a translation ID. + +This rule kicks in on: -## Exemptions and exceptions +- JSXText elements; +- specific JSXAttributes (`label` and `aria-label`) which expect a translated value. + +### Exemptions and exceptions A JSXText element or JSXAttribute `label` or `aria-label` of which the value is: @@ -32,3 +98,52 @@ A JSXText element or JSXAttribute `label` or `aria-label` of which the value is: are exempt from this rule. If this rule kicks in on a string value that you don't like, you can escape it by wrapping the string inside a JSXExpression: `{'my escaped value'}`. + +--- + +## `@kbn/i18n/i18n_translate_should_start_with_the_right_id` + +This rule checks every instance of `i18n.translate()` if the first parameter passed: + +1. has a string value, +2. if the parameter starts with the correct i18n app identifier for the file. + +It checks the repo for the `i18nrc.json` and `/x-pack/i18nrc.json` files and determines what the right i18n identifier should be. + +If the parameter is missing or does not start with the right i18n identifier, it can autofix the parameter. + +This rule is useful when defining translated values in plain functions (non-JSX), but it works in JSX as well. + +### Example + +This code: + +``` +// Filename: /x-pack/plugins/observability/public/my_function.ts + +function myFunction() { + const translations = [ + { + id: 'copy'; + label: i18n.translate() + } + ] +} +``` + +will be autofixed with: + +``` +import { i18n } from '@kbn/i18n'; + +function myFunction() { + const translations = [ + { + id: 'copy'; + label: i18n.translate('xpack.observability.myFunction.', { defaultMessage: '' }) + } + ] +} +``` + +If `i18n` has not been imported yet, the autofix will automatically add the import statement as well. diff --git a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.test.ts b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.test.ts index 6e01b89b2356..cea9fa1c333d 100644 --- a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.test.ts +++ b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.test.ts @@ -11,17 +11,15 @@ import { getI18nIdentifierFromFilePath } from './get_i18n_identifier_from_file_p const SYSTEMPATH = 'systemPath'; const testMap = [ - ['x-pack/plugins/observability/foo/bar/baz/header_actions.tsx', 'xpack.observability'], - ['x-pack/plugins/apm/public/components/app/correlations/correlations_table.tsx', 'xpack.apm'], - ['x-pack/plugins/cases/public/components/foo.tsx', 'xpack.cases'], + ['x-pack/plugins/observability/public/header_actions.tsx', 'xpack.observability'], + ['x-pack/plugins/apm/common/components/app/correlations/correlations_table.tsx', 'xpack.apm'], + ['x-pack/plugins/cases/server/components/foo.tsx', 'xpack.cases'], [ 'x-pack/plugins/synthetics/public/apps/synthetics/components/alerts/toggle_alert_flyout_button.tsx', 'xpack.synthetics', ], - [ - 'packages/kbn-alerts-ui-shared/src/alert_lifecycle_status_badge/index.tsx', - 'app_not_found_in_i18nrc', - ], + ['src/plugins/vis_types/gauge/public/editor/collections.ts', 'visTypeGauge'], + ['packages/kbn-alerts-ui-shared/src/alert_lifecycle_status_badge/index.tsx', 'alertsUIShared'], ]; describe('Get i18n Identifier for file', () => { diff --git a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.ts b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.ts index d23a42f4ebcf..7b39d119ee84 100644 --- a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.ts +++ b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_identifier_from_file_path.ts @@ -14,18 +14,38 @@ export function getI18nIdentifierFromFilePath(fileName: string, cwd: string) { const { dir } = parse(fileName); const relativePathToFile = dir.replace(cwd, ''); - const relativePathArray = relativePathToFile.split('/'); + // We need to match the path of the file that is being worked in with the path + // that is noted in the values inside the i18nrc.json object. + // These values differ depending on which i18nrc.json object you look at (there are multiple) + // so we need to account for both notations. + const relativePathArray = relativePathToFile.includes('src') + ? relativePathToFile.split('/').slice(1) + : relativePathToFile.split('/').slice(2); - const path = `${relativePathArray[2]}/${relativePathArray[3]}`; + const pluginNameIndex = relativePathArray.findIndex( + (el) => el === 'public' || el === 'server' || el === 'common' + ); + + const path = relativePathArray.slice(0, pluginNameIndex).join('/'); const xpackRC = resolve(join(__dirname, '../../../'), 'x-pack/.i18nrc.json'); + const rootRC = resolve(join(__dirname, '../../../'), '.i18nrc.json'); + + const xpackI18nrcFile = fs.readFileSync(xpackRC, 'utf8'); + const xpackI18nrc = JSON.parse(xpackI18nrcFile); + + const rootI18nrcFile = fs.readFileSync(rootRC, 'utf8'); + const rootI18nrc = JSON.parse(rootI18nrcFile); + + const allPaths = { ...xpackI18nrc.paths, ...rootI18nrc.paths }; - const i18nrcFile = fs.readFileSync(xpackRC, 'utf8'); - const i18nrc = JSON.parse(i18nrcFile); + if (Object.keys(allPaths).length === 0) return 'could_not_find_i18nrc'; - return i18nrc && i18nrc.paths - ? findKey(i18nrc.paths, (v) => - Array.isArray(v) ? v.find((e) => e === path) : typeof v === 'string' && v === path - ) ?? 'app_not_found_in_i18nrc' - : 'could_not_find_i18nrc'; + return ( + findKey(allPaths, (value) => + Array.isArray(value) + ? value.find((el) => el === path) + : typeof value === 'string' && value === path + ) ?? 'app_not_found_in_i18nrc' + ); } diff --git a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_import_fixer.ts b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_import_fixer.ts index cf3a7330f758..7b81c0f7a6b8 100644 --- a/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_import_fixer.ts +++ b/packages/kbn-eslint-plugin-i18n/helpers/get_i18n_import_fixer.ts @@ -10,10 +10,10 @@ import { SourceCode } from 'eslint'; export function getI18nImportFixer({ sourceCode, - mode, + translationFunction, }: { sourceCode: SourceCode; - mode: 'i18n.translate' | 'FormattedMessage'; + translationFunction: 'i18n.translate' | 'FormattedMessage'; }) { let existingI18nImportLineIndex = -1; let i18nImportLineToBeAdded = ''; @@ -27,7 +27,7 @@ export function getI18nImportFixer({ * * */ - if (mode === 'i18n.translate') { + if (translationFunction === 'i18n.translate') { existingI18nImportLineIndex = sourceCode.lines.findIndex((l) => l.includes("from '@kbn/i18n'")); const i18nImportLineInSource = sourceCode.lines[existingI18nImportLineIndex]; @@ -46,7 +46,7 @@ export function getI18nImportFixer({ } } - if (mode === 'FormattedMessage') { + if (translationFunction === 'FormattedMessage') { existingI18nImportLineIndex = sourceCode.lines.findIndex((l) => l.includes("from '@kbn/i18n-react'") ); @@ -83,21 +83,27 @@ export function getI18nImportFixer({ return { i18nImportLine: i18nImportLineToBeAdded, rangeToAddI18nImportLine: [start, end] as [number, number], - mode: 'replace', + replaceMode: 'replace', }; } // If the file doesn't have an import line for the translation package yet, we need to add it. // Pretty safe bet to add it underneath the import line for React. - const lineIndex = sourceCode.lines.findIndex((l) => l.includes("from 'react'")); + let lineIndex = sourceCode.lines.findIndex((l) => l.includes("from 'react'") || l.includes('*/')); + + if (lineIndex === -1) { + lineIndex = 0; + } + const targetLine = sourceCode.lines[lineIndex]; + // `getIndexFromLoc` is 0-based, so we need to add 1 to the line index. const start = sourceCode.getIndexFromLoc({ line: lineIndex + 1, column: 0 }); const end = start + targetLine.length; return { i18nImportLine: i18nImportLineToBeAdded, rangeToAddI18nImportLine: [start, end] as [number, number], - mode: 'insert', + replaceMode: 'insert', }; } diff --git a/packages/kbn-eslint-plugin-i18n/index.ts b/packages/kbn-eslint-plugin-i18n/index.ts index be5661cf46de..dd99785204c3 100644 --- a/packages/kbn-eslint-plugin-i18n/index.ts +++ b/packages/kbn-eslint-plugin-i18n/index.ts @@ -8,6 +8,7 @@ import { StringsShouldBeTranslatedWithI18n } from './rules/strings_should_be_translated_with_i18n'; import { StringsShouldBeTranslatedWithFormattedMessage } from './rules/strings_should_be_translated_with_formatted_message'; +import { I18nTranslateShouldStartWithTheRightId } from './rules/i18n_translate_should_start_with_the_right_id'; /** * Custom ESLint rules, add `'@kbn/eslint-plugin-i18n'` to your eslint config to use them @@ -17,4 +18,5 @@ export const rules = { strings_should_be_translated_with_i18n: StringsShouldBeTranslatedWithI18n, strings_should_be_translated_with_formatted_message: StringsShouldBeTranslatedWithFormattedMessage, + i18n_translate_should_start_with_the_right_id: I18nTranslateShouldStartWithTheRightId, }; diff --git a/packages/kbn-eslint-plugin-i18n/kibana.jsonc b/packages/kbn-eslint-plugin-i18n/kibana.jsonc index 72e051941db6..b234cc835ed3 100644 --- a/packages/kbn-eslint-plugin-i18n/kibana.jsonc +++ b/packages/kbn-eslint-plugin-i18n/kibana.jsonc @@ -1,6 +1,6 @@ { "type": "shared-common", "id": "@kbn/eslint-plugin-i18n", - "owner": "@elastic/obs-knowledge-team", + "owner": ["@elastic/obs-knowledge-team", "@elastic/kibana-operations"], "devOnly": true } diff --git a/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.test.ts b/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.test.ts new file mode 100644 index 000000000000..49bdb03a4f47 --- /dev/null +++ b/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.test.ts @@ -0,0 +1,134 @@ +/* + * 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 { RuleTester } from 'eslint'; +import { + I18nTranslateShouldStartWithTheRightId, + RULE_WARNING_MESSAGE, +} from './i18n_translate_should_start_with_the_right_id'; + +const tsTester = [ + '@typescript-eslint/parser', + new RuleTester({ + parser: require.resolve('@typescript-eslint/parser'), + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018, + ecmaFeatures: { + jsx: true, + }, + }, + }), +] as const; + +const babelTester = [ + '@babel/eslint-parser', + new RuleTester({ + parser: require.resolve('@babel/eslint-parser'), + parserOptions: { + sourceType: 'module', + ecmaVersion: 2018, + requireConfigFile: false, + babelOptions: { + presets: ['@kbn/babel-preset/node_preset'], + }, + }, + }), +] as const; + +const invalid: RuleTester.InvalidTestCase[] = [ + { + name: 'When a string literal is passed to i18n.translate, it should start with the correct i18n identifier.', + filename: '/x-pack/plugins/observability/public/test_component.ts', + code: ` +import { i18n } from '@kbn/i18n'; + +function TestComponent() { + const foo = i18n.translate('foo'); +}`, + errors: [ + { + line: 5, + message: RULE_WARNING_MESSAGE, + }, + ], + output: ` +import { i18n } from '@kbn/i18n'; + +function TestComponent() { + const foo = i18n.translate('xpack.observability.testComponent.', { defaultMessage: '' }); +}`, + }, + { + name: 'When no string literal is passed to i18n.translate, it should start with the correct i18n identifier.', + filename: '/x-pack/plugins/observability/public/test_component.ts', + code: ` +import { i18n } from '@kbn/i18n'; + +function TestComponent() { + const foo = i18n.translate(); +}`, + errors: [ + { + line: 5, + message: RULE_WARNING_MESSAGE, + }, + ], + output: ` +import { i18n } from '@kbn/i18n'; + +function TestComponent() { + const foo = i18n.translate('xpack.observability.testComponent.', { defaultMessage: '' }); +}`, + }, + { + name: 'When i18n is not imported yet, the rule should add it.', + filename: '/x-pack/plugins/observability/public/test_component.ts', + code: ` +function TestComponent() { + const foo = i18n.translate(); +}`, + errors: [ + { + line: 3, + message: RULE_WARNING_MESSAGE, + }, + ], + output: ` +import { i18n } from '@kbn/i18n'; +function TestComponent() { + const foo = i18n.translate('xpack.observability.testComponent.', { defaultMessage: '' }); +}`, + }, +]; + +const valid: RuleTester.ValidTestCase[] = [ + { + name: invalid[0].name, + filename: invalid[0].filename, + code: invalid[0].output as string, + }, + { + name: invalid[1].name, + filename: invalid[1].filename, + code: invalid[1].output as string, + }, +]; + +for (const [name, tester] of [tsTester, babelTester]) { + describe(name, () => { + tester.run( + '@kbn/i18n_translate_should_start_with_the_right_id', + I18nTranslateShouldStartWithTheRightId, + { + valid, + invalid, + } + ); + }); +} diff --git a/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.ts b/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.ts new file mode 100644 index 000000000000..d6510ba588a4 --- /dev/null +++ b/packages/kbn-eslint-plugin-i18n/rules/i18n_translate_should_start_with_the_right_id.ts @@ -0,0 +1,82 @@ +/* + * 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 { TSESTree } from '@typescript-eslint/typescript-estree'; +import type { Rule } from 'eslint'; +import { getI18nIdentifierFromFilePath } from '../helpers/get_i18n_identifier_from_file_path'; +import { getFunctionName } from '../helpers/get_function_name'; +import { getI18nImportFixer } from '../helpers/get_i18n_import_fixer'; +import { isTruthy } from '../helpers/utils'; + +export const RULE_WARNING_MESSAGE = + 'First parameter passed to i18n.translate should start with the correct i18n identifier for this file. Correct it or use the autofix suggestion.'; + +export const I18nTranslateShouldStartWithTheRightId: Rule.RuleModule = { + meta: { + type: 'suggestion', + fixable: 'code', + }, + create(context) { + const { cwd, filename, getScope, sourceCode, report } = context; + + return { + CallExpression: (node: TSESTree.CallExpression) => { + const { callee } = node; + + if ( + !callee || + !('object' in callee) || + !('property' in callee) || + !('name' in callee.object) || + !('name' in callee.property) || + callee.object.name !== 'i18n' || + callee.property.name !== 'translate' + ) + return; + + const identifier = + Array.isArray(node.arguments) && + node.arguments.length && + 'value' in node.arguments[0] && + typeof node.arguments[0].value === 'string' && + node.arguments[0].value; + + const i18nAppId = getI18nIdentifierFromFilePath(filename, cwd); + const functionDeclaration = getScope().block as TSESTree.FunctionDeclaration; + const functionName = getFunctionName(functionDeclaration); + + // Check if i18n has already been imported into the file + const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, replaceMode } = + getI18nImportFixer({ + sourceCode, + translationFunction: 'i18n.translate', + }); + + if (!identifier || (identifier && !identifier.startsWith(`${i18nAppId}.`))) { + report({ + node: node as any, + message: RULE_WARNING_MESSAGE, + fix(fixer) { + return [ + fixer.replaceTextRange( + node.range, + `i18n.translate('${i18nAppId}.${functionName}.', { defaultMessage: '' })` + ), + !hasI18nImportLine && rangeToAddI18nImportLine + ? replaceMode === 'replace' + ? fixer.replaceTextRange(rangeToAddI18nImportLine, i18nImportLine) + : fixer.insertTextAfterRange(rangeToAddI18nImportLine, `\n${i18nImportLine}`) + : null, + ].filter(isTruthy); + }, + }); + } + }, + } as Rule.RuleListener; + }, +}; diff --git a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.test.ts b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.test.ts index 009fac255fc6..6faf6732f901 100644 --- a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.test.ts +++ b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.test.ts @@ -7,7 +7,10 @@ */ import { RuleTester } from 'eslint'; -import { StringsShouldBeTranslatedWithFormattedMessage } from './strings_should_be_translated_with_formatted_message'; +import { + StringsShouldBeTranslatedWithFormattedMessage, + RULE_WARNING_MESSAGE, +} from './strings_should_be_translated_with_formatted_message'; const tsTester = [ '@typescript-eslint/parser', @@ -41,7 +44,7 @@ const babelTester = [ const invalid: RuleTester.InvalidTestCase[] = [ { name: 'A JSX element with a string literal should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -53,7 +56,7 @@ function TestComponent() { errors: [ { line: 6, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -64,7 +67,7 @@ function TestComponent() { return (
    ) @@ -72,7 +75,7 @@ function TestComponent() { }, { name: 'A JSX element with a string literal that are inside an Eui component should take the component name of the parent into account', - filename: 'x-pack/plugins/observability/public/another_component.tsx', + filename: '/x-pack/plugins/observability/public/another_component.tsx', code: ` import React from 'react'; @@ -90,7 +93,7 @@ function AnotherComponent() { errors: [ { line: 9, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -104,7 +107,7 @@ function AnotherComponent() { @@ -115,7 +118,7 @@ function AnotherComponent() { }, { name: 'When no import of the translation module is present, the import line should be added', - filename: 'x-pack/plugins/observability/public/yet_another_component.tsx', + filename: '/x-pack/plugins/observability/public/yet_another_component.tsx', code: ` import React from 'react'; @@ -129,7 +132,7 @@ function YetAnotherComponent() { errors: [ { line: 7, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -141,7 +144,7 @@ function YetAnotherComponent() {
    @@ -150,7 +153,7 @@ function YetAnotherComponent() { }, { name: 'Import lines without the necessary translation module should be updated to include i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { SomeOtherModule } from '@kbn/i18n-react'; @@ -163,7 +166,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -172,13 +175,13 @@ import { SomeOtherModule, FormattedMessage } from '@kbn/i18n-react'; function TestComponent() { return ( - } /> + } /> ) }`, }, { name: 'JSX elements that have a label or aria-label prop with a string value should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -191,7 +194,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -200,13 +203,13 @@ import { FormattedMessage } from '@kbn/i18n-react'; function TestComponent() { return ( - } /> + } /> ) }`, }, { name: 'JSX elements that have a label or aria-label prop with a JSXExpression value that is a string should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -219,7 +222,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with . Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -228,7 +231,7 @@ function TestComponent() { function TestComponent() { return ( - } /> + } /> ) }`, }, @@ -237,7 +240,7 @@ function TestComponent() { const valid: RuleTester.ValidTestCase[] = [ { name: 'A JSXText element inside a EuiCode component should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -249,7 +252,7 @@ function TestComponent() { }, { name: 'A JSXText element that contains anything other than alpha characters should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -261,7 +264,7 @@ function TestComponent() { }, { name: 'A JSXText element that is wrapped in three backticks (markdown) should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; diff --git a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.ts b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.ts index 77b591895103..ea96cf313d1b 100644 --- a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.ts +++ b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_formatted_message.ts @@ -14,6 +14,8 @@ import { getFunctionName } from '../helpers/get_function_name'; import { getI18nImportFixer } from '../helpers/get_i18n_import_fixer'; import { cleanString, isTruthy } from '../helpers/utils'; +export const RULE_WARNING_MESSAGE = + 'Strings should be translated with . Use the autofix suggestion or add your own.'; export const StringsShouldBeTranslatedWithFormattedMessage: Rule.RuleModule = { meta: { type: 'suggestion', @@ -44,17 +46,16 @@ export const StringsShouldBeTranslatedWithFormattedMessage: Rule.RuleModule = { const translationIdSuggestion = `${i18nAppId}.${functionName}.${intent}`; // 'xpack.observability.overview.logs.loadMoreLabel' // Check if i18n has already been imported into the file - const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, mode } = + const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, replaceMode } = getI18nImportFixer({ sourceCode, - mode: 'FormattedMessage', + translationFunction: 'FormattedMessage', }); // Show warning to developer and offer autofix suggestion report({ node: node as any, - message: - 'Strings should be translated with . Use the autofix suggestion or add your own.', + message: RULE_WARNING_MESSAGE, fix(fixer) { return [ fixer.replaceText( @@ -65,7 +66,7 @@ export const StringsShouldBeTranslatedWithFormattedMessage: Rule.RuleModule = { />` ), !hasI18nImportLine && rangeToAddI18nImportLine - ? mode === 'replace' + ? replaceMode === 'replace' ? fixer.replaceTextRange(rangeToAddI18nImportLine, i18nImportLine) : fixer.insertTextAfterRange(rangeToAddI18nImportLine, `\n${i18nImportLine}`) : null, @@ -106,17 +107,16 @@ export const StringsShouldBeTranslatedWithFormattedMessage: Rule.RuleModule = { const translationIdSuggestion = `${i18nAppId}.${functionName}.${intent}`; // 'xpack.observability.overview.logs.loadMoreLabel' // Check if i18n has already been imported into the file. - const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, mode } = + const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, replaceMode } = getI18nImportFixer({ sourceCode, - mode: 'FormattedMessage', + translationFunction: 'FormattedMessage', }); // Show warning to developer and offer autofix suggestion report({ node: node as any, - message: - 'Strings should be translated with . Use the autofix suggestion or add your own.', + message: RULE_WARNING_MESSAGE, fix(fixer) { return [ fixer.replaceTextRange( @@ -124,7 +124,7 @@ export const StringsShouldBeTranslatedWithFormattedMessage: Rule.RuleModule = { `{}` ), !hasI18nImportLine && rangeToAddI18nImportLine - ? mode === 'replace' + ? replaceMode === 'replace' ? fixer.replaceTextRange(rangeToAddI18nImportLine, i18nImportLine) : fixer.insertTextAfterRange(rangeToAddI18nImportLine, `\n${i18nImportLine}`) : null, diff --git a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.test.ts b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.test.ts index f470ed885682..3142d368b076 100644 --- a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.test.ts +++ b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.test.ts @@ -7,7 +7,10 @@ */ import { RuleTester } from 'eslint'; -import { StringsShouldBeTranslatedWithI18n } from './strings_should_be_translated_with_i18n'; +import { + StringsShouldBeTranslatedWithI18n, + RULE_WARNING_MESSAGE, +} from './strings_should_be_translated_with_i18n'; const tsTester = [ '@typescript-eslint/parser', @@ -41,7 +44,7 @@ const babelTester = [ const invalid: RuleTester.InvalidTestCase[] = [ { name: 'A JSX element with a string literal should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -53,7 +56,7 @@ function TestComponent() { errors: [ { line: 6, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -62,13 +65,13 @@ import { i18n } from '@kbn/i18n'; function TestComponent() { return ( -
    {i18n.translate('app_not_found_in_i18nrc.testComponent.div.thisIsATestLabel', { defaultMessage: 'This is a test' })}
    +
    {i18n.translate('xpack.observability.testComponent.div.thisIsATestLabel', { defaultMessage: 'This is a test' })}
    ) }`, }, { name: 'A JSX element with a string literal that are inside an Eui component should take the component name of the parent into account', - filename: 'x-pack/plugins/observability/public/another_component.tsx', + filename: '/x-pack/plugins/observability/public/another_component.tsx', code: ` import React from 'react'; @@ -86,7 +89,7 @@ function AnotherComponent() { errors: [ { line: 9, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -98,7 +101,7 @@ function AnotherComponent() { - {i18n.translate('app_not_found_in_i18nrc.anotherComponent.thisIsATestButtonLabel', { defaultMessage: 'This is a test' })} + {i18n.translate('xpack.observability.anotherComponent.thisIsATestButtonLabel', { defaultMessage: 'This is a test' })} @@ -107,7 +110,7 @@ function AnotherComponent() { }, { name: 'When no import of the translation module is present, the import line should be added', - filename: 'x-pack/plugins/observability/public/yet_another_component.tsx', + filename: '/x-pack/plugins/observability/public/yet_another_component.tsx', code: ` import React from 'react'; @@ -121,7 +124,7 @@ function YetAnotherComponent() { errors: [ { line: 7, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -131,14 +134,14 @@ import { i18n } from '@kbn/i18n'; function YetAnotherComponent() { return (
    - {i18n.translate('app_not_found_in_i18nrc.yetAnotherComponent.selectMeSelectLabel', { defaultMessage: 'Select me' })} + {i18n.translate('xpack.observability.yetAnotherComponent.selectMeSelectLabel', { defaultMessage: 'Select me' })}
    ) }`, }, { name: 'Import lines without the necessary translation module should be updated to include i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { SomeOtherModule } from '@kbn/i18n'; @@ -151,7 +154,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -160,13 +163,13 @@ import { SomeOtherModule, i18n } from '@kbn/i18n'; function TestComponent() { return ( - + ) }`, }, { name: 'JSX elements that have a label or aria-label prop with a string value should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { i18n } from '@kbn/i18n'; @@ -179,7 +182,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -188,13 +191,13 @@ import { i18n } from '@kbn/i18n'; function TestComponent() { return ( - + ) }`, }, { name: 'JSX elements that have a label or aria-label prop with a JSXExpression value that is a string should be translated with i18n', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; import { i18n } from '@kbn/i18n'; @@ -207,7 +210,7 @@ function TestComponent() { errors: [ { line: 7, - message: `Strings should be translated with i18n. Use the autofix suggestion or add your own.`, + message: RULE_WARNING_MESSAGE, }, ], output: ` @@ -216,7 +219,7 @@ import { i18n } from '@kbn/i18n'; function TestComponent() { return ( - + ) }`, }, @@ -225,7 +228,7 @@ function TestComponent() { const valid: RuleTester.ValidTestCase[] = [ { name: 'A JSXText element inside a EuiCode component should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -237,7 +240,7 @@ function TestComponent() { }, { name: 'A JSXText element that contains anything other than alpha characters should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; @@ -249,7 +252,7 @@ function TestComponent() { }, { name: 'A JSXText element that is wrapped in three backticks (markdown) should not be translated', - filename: 'x-pack/plugins/observability/public/test_component.tsx', + filename: '/x-pack/plugins/observability/public/test_component.tsx', code: ` import React from 'react'; diff --git a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.ts b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.ts index fea04d33d555..ec1630de115e 100644 --- a/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.ts +++ b/packages/kbn-eslint-plugin-i18n/rules/strings_should_be_translated_with_i18n.ts @@ -14,6 +14,9 @@ import { getFunctionName } from '../helpers/get_function_name'; import { getI18nImportFixer } from '../helpers/get_i18n_import_fixer'; import { cleanString, isTruthy } from '../helpers/utils'; +export const RULE_WARNING_MESSAGE = + 'Strings should be translated with i18n. Use the autofix suggestion or add your own.'; + export const StringsShouldBeTranslatedWithI18n: Rule.RuleModule = { meta: { type: 'suggestion', @@ -44,17 +47,16 @@ export const StringsShouldBeTranslatedWithI18n: Rule.RuleModule = { const translationIdSuggestion = `${i18nAppId}.${functionName}.${intent}`; // 'xpack.observability.overview.logs.loadMoreLabel' // Check if i18n has already been imported into the file - const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, mode } = + const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, replaceMode } = getI18nImportFixer({ sourceCode, - mode: 'i18n.translate', + translationFunction: 'i18n.translate', }); // Show warning to developer and offer autofix suggestion report({ node: node as any, - message: - 'Strings should be translated with i18n. Use the autofix suggestion or add your own.', + message: RULE_WARNING_MESSAGE, fix(fixer) { return [ fixer.replaceText( @@ -62,7 +64,7 @@ export const StringsShouldBeTranslatedWithI18n: Rule.RuleModule = { `${whiteSpaces}{i18n.translate('${translationIdSuggestion}', { defaultMessage: '${value}' })}` ), !hasI18nImportLine && rangeToAddI18nImportLine - ? mode === 'replace' + ? replaceMode === 'replace' ? fixer.replaceTextRange(rangeToAddI18nImportLine, i18nImportLine) : fixer.insertTextAfterRange(rangeToAddI18nImportLine, `\n${i18nImportLine}`) : null, @@ -103,17 +105,16 @@ export const StringsShouldBeTranslatedWithI18n: Rule.RuleModule = { const translationIdSuggestion = `${i18nAppId}.${functionName}.${intent}`; // 'xpack.observability.overview.logs.loadMoreLabel' // Check if i18n has already been imported into the file. - const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, mode } = + const { hasI18nImportLine, i18nImportLine, rangeToAddI18nImportLine, replaceMode } = getI18nImportFixer({ sourceCode, - mode: 'i18n.translate', + translationFunction: 'i18n.translate', }); // Show warning to developer and offer autofix suggestion report({ node: node as any, - message: - 'Strings should be translated with i18n. Use the autofix suggestion or add your own.', + message: RULE_WARNING_MESSAGE, fix(fixer) { return [ fixer.replaceTextRange( @@ -121,7 +122,7 @@ export const StringsShouldBeTranslatedWithI18n: Rule.RuleModule = { `{i18n.translate('${translationIdSuggestion}', { defaultMessage: '${val}' })}` ), !hasI18nImportLine && rangeToAddI18nImportLine - ? mode === 'replace' + ? replaceMode === 'replace' ? fixer.replaceTextRange(rangeToAddI18nImportLine, i18nImportLine) : fixer.insertTextAfterRange(rangeToAddI18nImportLine, `\n${i18nImportLine}`) : null, diff --git a/packages/kbn-mock-idp-plugin/common/constants.ts b/packages/kbn-mock-idp-plugin/common/constants.ts new file mode 100644 index 000000000000..6fb547558757 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/common/constants.ts @@ -0,0 +1,24 @@ +/* + * 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 { resolve } from 'path'; + +export const MOCK_IDP_PLUGIN_PATH = resolve(__dirname, '..'); +export const MOCK_IDP_METADATA_PATH = resolve(MOCK_IDP_PLUGIN_PATH, 'metadata.xml'); + +export const MOCK_IDP_LOGIN_PATH = '/mock_idp/login'; +export const MOCK_IDP_LOGOUT_PATH = '/mock_idp/logout'; + +export const MOCK_IDP_REALM_NAME = 'mock-idp'; +export const MOCK_IDP_ENTITY_ID = 'urn:mock-idp'; // Must match `entityID` in `metadata.xml` +export const MOCK_IDP_ROLE_MAPPING_NAME = 'mock-idp-mapping'; + +export const MOCK_IDP_ATTRIBUTE_PRINCIPAL = 'http://saml.elastic-cloud.com/attributes/principal'; +export const MOCK_IDP_ATTRIBUTE_ROLES = 'http://saml.elastic-cloud.com/attributes/roles'; +export const MOCK_IDP_ATTRIBUTE_EMAIL = 'http://saml.elastic-cloud.com/attributes/email'; +export const MOCK_IDP_ATTRIBUTE_NAME = 'http://saml.elastic-cloud.com/attributes/name'; diff --git a/packages/kbn-mock-idp-plugin/common/index.ts b/packages/kbn-mock-idp-plugin/common/index.ts new file mode 100644 index 000000000000..aaaffc15f10f --- /dev/null +++ b/packages/kbn-mock-idp-plugin/common/index.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { + MOCK_IDP_PLUGIN_PATH, + MOCK_IDP_METADATA_PATH, + MOCK_IDP_LOGIN_PATH, + MOCK_IDP_LOGOUT_PATH, + MOCK_IDP_REALM_NAME, + MOCK_IDP_ENTITY_ID, + MOCK_IDP_ROLE_MAPPING_NAME, + MOCK_IDP_ATTRIBUTE_PRINCIPAL, + MOCK_IDP_ATTRIBUTE_ROLES, + MOCK_IDP_ATTRIBUTE_EMAIL, + MOCK_IDP_ATTRIBUTE_NAME, +} from './constants'; +export { + createMockIdpMetadata, + createSAMLResponse, + ensureSAMLRoleMapping, + parseSAMLAuthnRequest, +} from './utils'; diff --git a/packages/kbn-mock-idp-plugin/common/utils.ts b/packages/kbn-mock-idp-plugin/common/utils.ts new file mode 100644 index 000000000000..5d55fbc56568 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/common/utils.ts @@ -0,0 +1,231 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; +import { SignedXml } from 'xml-crypto'; +import { KBN_KEY_PATH, KBN_CERT_PATH } from '@kbn/dev-utils'; +import { readFile } from 'fs/promises'; +import zlib from 'zlib'; +import { promisify } from 'util'; +import { parseString } from 'xml2js'; +import { X509Certificate } from 'crypto'; + +import { + MOCK_IDP_REALM_NAME, + MOCK_IDP_ENTITY_ID, + MOCK_IDP_ROLE_MAPPING_NAME, + MOCK_IDP_ATTRIBUTE_PRINCIPAL, + MOCK_IDP_ATTRIBUTE_ROLES, + MOCK_IDP_ATTRIBUTE_EMAIL, + MOCK_IDP_ATTRIBUTE_NAME, + MOCK_IDP_LOGIN_PATH, + MOCK_IDP_LOGOUT_PATH, +} from './constants'; + +const inflateRawAsync = promisify(zlib.inflateRaw); +const parseStringAsync = promisify(parseString); + +/** + * Creates XML metadata for our mock identity provider. + * + * This can be saved to file and used to configure Elasticsearch SAML realm. + * + * @param kibanaUrl Fully qualified URL where Kibana is hosted (including base path) + */ +export async function createMockIdpMetadata(kibanaUrl: string) { + const signingKey = await readFile(KBN_CERT_PATH); + const cert = new X509Certificate(signingKey); + const trimTrailingSlash = (url: string) => (url.endsWith('/') ? url.slice(0, -1) : url); + + return ` + + + + + + ${cert.raw.toString('base64')} + + + + + + + + + + `; +} + +/** + * Creates a SAML response that can be passed directly to the Kibana ACS endpoint to authenticate a user. + * + * @example Create a SAML response. + * + * ```ts + * const samlResponse = await createSAMLResponse({ + * username: '1234567890', + * email: 'mail@elastic.co', + * fullname: 'Test User', + * roles: ['t1_analyst', 'editor'], + * }) + * ``` + * + * @example Authenticate user with SAML response. + * + * ```ts + * fetch('/api/security/saml/callback', { + * method: 'POST', + * body: JSON.stringify({ SAMLResponse: samlResponse }), + * redirect: 'manual' + * }) + * ``` + */ +export async function createSAMLResponse(options: { + /** Fully qualified URL where Kibana is hosted (including base path) */ + kibanaUrl: string; + /** ID from SAML authentication request */ + authnRequestId?: string; + username: string; + fullname?: string; + email?: string; + roles: string[]; +}) { + const issueInstant = new Date().toISOString(); + const notOnOrAfter = new Date(Date.now() + 3600 * 1000).toISOString(); + + const samlAssertionTemplateXML = ` + + ${MOCK_IDP_ENTITY_ID} + + _643ec1b3f5673583b9f9a1e9e73a36daa2a3748f + + + + + + + urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified + + + + + ${options.username} + + + ${options.roles + .map( + (role) => `${role}` + ) + .join('')} + + ${ + options.email + ? ` + ${options.email} + ` + : '' + } + ${ + options.fullname + ? ` + ${options.fullname} + ` + : '' + } + + + `; + + const signature = new SignedXml(); + signature.signatureAlgorithm = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'; + signature.signingKey = await readFile(KBN_KEY_PATH); + + // Adds a reference to a `Assertion` xml element and an array of transform algorithms to be used during signing. + signature.addReference( + `//*[local-name(.)='Assertion']`, + [ + 'http://www.w3.org/2000/09/xmldsig#enveloped-signature', + 'http://www.w3.org/2001/10/xml-exc-c14n#', + ], + 'http://www.w3.org/2001/04/xmlenc#sha256' + ); + + signature.computeSignature(samlAssertionTemplateXML, { + location: { reference: `//*[local-name(.)='Issuer']`, action: 'after' }, + }); + + const value = await Buffer.from( + ` + + ${MOCK_IDP_ENTITY_ID} + + + ${signature.getSignedXml()} + + ` + ).toString('base64'); + + return value; +} + +/** + * Creates the role mapping required for developers to authenticate using SAML. + */ +export async function ensureSAMLRoleMapping(client: Client) { + return client.transport.request({ + method: 'PUT', + path: `/_security/role_mapping/${MOCK_IDP_ROLE_MAPPING_NAME}`, + body: { + enabled: true, + role_templates: [ + { + template: '{"source":"{{#tojson}}groups{{/tojson}}"}', + format: 'json', + }, + ], + rules: { + all: [ + { + field: { + 'realm.name': MOCK_IDP_REALM_NAME, + }, + }, + ], + }, + }, + }); +} + +interface SAMLAuthnRequest { + 'saml2p:AuthnRequest': { + $: { + AssertionConsumerServiceURL: string; + Destination: string; + ID: string; + IssueInstant: string; + }; + }; +} + +export async function parseSAMLAuthnRequest(samlRequest: string) { + const inflatedSAMLRequest = (await inflateRawAsync(Buffer.from(samlRequest, 'base64'))) as Buffer; + const parsedSAMLRequest = (await parseStringAsync( + inflatedSAMLRequest.toString() + )) as SAMLAuthnRequest; + return parsedSAMLRequest['saml2p:AuthnRequest'].$; +} diff --git a/packages/kbn-mock-idp-plugin/kibana.jsonc b/packages/kbn-mock-idp-plugin/kibana.jsonc new file mode 100644 index 000000000000..929d7b9b990d --- /dev/null +++ b/packages/kbn-mock-idp-plugin/kibana.jsonc @@ -0,0 +1,11 @@ +{ + "type": "plugin", + "id": "@kbn/mock-idp-plugin", + "owner": "@elastic/kibana-security", + "devOnly": true, + "plugin": { + "id": "mockIdpPlugin", + "server": true, + "browser": false + } +} \ No newline at end of file diff --git a/packages/kbn-subscription-tracking/package.json b/packages/kbn-mock-idp-plugin/package.json similarity index 69% rename from packages/kbn-subscription-tracking/package.json rename to packages/kbn-mock-idp-plugin/package.json index e9dd11b56c81..456a2cfa5ce3 100644 --- a/packages/kbn-subscription-tracking/package.json +++ b/packages/kbn-mock-idp-plugin/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/subscription-tracking", + "name": "@kbn/mock-idp-plugin", "private": true, "version": "1.0.0", "license": "SSPL-1.0 OR Elastic License 2.0" diff --git a/packages/kbn-subscription-tracking/jest.config.js b/packages/kbn-mock-idp-plugin/server/index.ts similarity index 74% rename from packages/kbn-subscription-tracking/jest.config.js rename to packages/kbn-mock-idp-plugin/server/index.ts index edc1839850da..db807851d456 100644 --- a/packages/kbn-subscription-tracking/jest.config.js +++ b/packages/kbn-mock-idp-plugin/server/index.ts @@ -6,8 +6,4 @@ * Side Public License, v 1. */ -module.exports = { - preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-subscription-tracking'], -}; +export { plugin } from './plugin'; diff --git a/packages/kbn-mock-idp-plugin/server/plugin.ts b/packages/kbn-mock-idp-plugin/server/plugin.ts new file mode 100644 index 000000000000..20c115d80cf2 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/server/plugin.ts @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { PluginInitializer, Plugin } from '@kbn/core-plugins-server'; +import { schema } from '@kbn/config-schema'; + +import { + MOCK_IDP_LOGIN_PATH, + MOCK_IDP_LOGOUT_PATH, + createSAMLResponse, + parseSAMLAuthnRequest, +} from '../common'; + +export const plugin: PluginInitializer = async (): Promise => ({ + setup(core) { + core.http.resources.register( + { + path: MOCK_IDP_LOGIN_PATH, + validate: { + query: schema.object({ + SAMLRequest: schema.string(), + }), + }, + options: { authRequired: false }, + }, + async (context, request, response) => { + let samlRequest: Awaited>; + try { + samlRequest = await parseSAMLAuthnRequest(request.query.SAMLRequest); + } catch (error) { + return response.badRequest({ + body: '[request query.SAMLRequest]: value is not valid SAMLRequest.', + }); + } + + const userRoles: Array<[string, string]> = [ + ['system_indices_superuser', 'system_indices_superuser'], + ['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'], + ]; + + const samlResponses = await Promise.all( + userRoles.map(([username, role]) => + createSAMLResponse({ + authnRequestId: samlRequest.ID, + kibanaUrl: samlRequest.AssertionConsumerServiceURL, + username, + roles: [role], + }) + ) + ); + + return response.renderHtml({ + body: ` + + Mock Identity Provider + + +

    Mock Identity Provider

    +
    +

    Pick a role:

    +
      + ${userRoles + .map( + ([username], i) => + ` +
    • + +
    • + ` + ) + .join('')} +
    + + + `, + }); + } + ); + + core.http.resources.register( + { + path: `${MOCK_IDP_LOGIN_PATH}/submit.js`, + validate: false, + options: { authRequired: false }, + }, + (context, request, response) => { + return response.renderJs({ body: 'document.getElementById("loginForm").submit();' }); + } + ); + + core.http.resources.register( + { + path: MOCK_IDP_LOGOUT_PATH, + validate: false, + options: { authRequired: false }, + }, + async (context, request, response) => { + return response.redirected({ headers: { location: '/' } }); + } + ); + }, + start() {}, + stop() {}, +}); diff --git a/packages/kbn-mock-idp-plugin/tsconfig.json b/packages/kbn-mock-idp-plugin/tsconfig.json new file mode 100644 index 000000000000..1420a34208f1 --- /dev/null +++ b/packages/kbn-mock-idp-plugin/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types" + }, + "include": [ + "**/*.ts", + "**/*.tsx" + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/core-plugins-server", + "@kbn/config-schema", + "@kbn/dev-utils" + ] +} diff --git a/packages/kbn-profiling-utils/common/functions.ts b/packages/kbn-profiling-utils/common/functions.ts index 47bf0a310007..50cbd40a6d19 100644 --- a/packages/kbn-profiling-utils/common/functions.ts +++ b/packages/kbn-profiling-utils/common/functions.ts @@ -207,3 +207,21 @@ export const topNFunctionSortFieldRt = t.union([ t.literal(TopNFunctionSortField.AnnualizedCo2), t.literal(TopNFunctionSortField.AnnualizedDollarCost), ]); + +export enum TopNComparisonFunctionSortField { + ComparisonRank = 'comparison_rank', + ComparisonFrame = 'comparison_frame', + ComparisonSamples = 'comparison_samples', + ComparisonSelfCPU = 'comparison_selfCPU', + ComparisonTotalCPU = 'comparison_totalCPU', + ComparisonDiff = 'comparison_diff', +} + +export const topNComparisonFunctionSortFieldRt = t.union([ + t.literal(TopNComparisonFunctionSortField.ComparisonRank), + t.literal(TopNComparisonFunctionSortField.ComparisonFrame), + t.literal(TopNComparisonFunctionSortField.ComparisonSamples), + t.literal(TopNComparisonFunctionSortField.ComparisonSelfCPU), + t.literal(TopNComparisonFunctionSortField.ComparisonTotalCPU), + t.literal(TopNComparisonFunctionSortField.ComparisonDiff), +]); diff --git a/packages/kbn-profiling-utils/index.ts b/packages/kbn-profiling-utils/index.ts index 38ab8d11be23..54376e29b6d1 100644 --- a/packages/kbn-profiling-utils/index.ts +++ b/packages/kbn-profiling-utils/index.ts @@ -30,6 +30,8 @@ export { createTopNFunctions, TopNFunctionSortField, topNFunctionSortFieldRt, + TopNComparisonFunctionSortField, + topNComparisonFunctionSortFieldRt, } from './common/functions'; export type { CalleeTree } from './common/callee'; diff --git a/packages/kbn-search-api-panels/components/ingest_data.tsx b/packages/kbn-search-api-panels/components/ingest_data.tsx index 0b0e11b13618..f8ba59d29bf3 100644 --- a/packages/kbn-search-api-panels/components/ingest_data.tsx +++ b/packages/kbn-search-api-panels/components/ingest_data.tsx @@ -6,25 +6,22 @@ * Side Public License, v 1. */ -import React, { useState } from 'react'; +import React from 'react'; -import { EuiCheckableCard, EuiFormFieldset, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; +import { EuiSpacer, EuiTitle } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { ApplicationStart } from '@kbn/core-application-browser'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import { CodeBox } from './code_box'; import { LanguageDefinition } from '../types'; import { OverviewPanel } from './overview_panel'; -import { IntegrationsPanel } from './integrations_panel'; - +import { IngestionsPanel } from './ingestions_panel'; interface IngestDataProps { codeSnippet: string; selectedLanguage: LanguageDefinition; setSelectedLanguage: (language: LanguageDefinition) => void; docLinks: { beats: string; - connectors: string; - integrations: string; logstash: string; }; assetBasePath: string; @@ -32,6 +29,7 @@ interface IngestDataProps { sharePlugin: SharePluginStart; languages: LanguageDefinition[]; consoleRequest?: string; + additionalIngestionPanel?: React.ReactNode; } export const IngestData: React.FC = ({ @@ -44,115 +42,45 @@ export const IngestData: React.FC = ({ sharePlugin, languages, consoleRequest, + additionalIngestionPanel, }) => { - const [selectedIngestMethod, setSelectedIngestMethod] = useState< - 'ingestViaApi' | 'ingestViaIntegration' - >('ingestViaApi'); return ( - ) : ( - - ) + } - links={[ - ...(selectedLanguage.apiReference - ? [ - { - href: selectedLanguage.apiReference, - label: i18n.translate('searchApiPanels.welcomeBanner.ingestData.clientDocLink', { - defaultMessage: '{languageName} API reference', - values: { languageName: selectedLanguage.name }, - }), - }, - ] - : []), - { - href: docLinks.integrations, - label: i18n.translate('searchApiPanels.welcomeBanner.ingestData.integrationsLink', { - defaultMessage: 'About Integrations', - }), - }, - ]} + links={[]} title={i18n.translate('searchApiPanels.welcomeBanner.ingestData.title', { defaultMessage: 'Ingest data', })} > - - -

    - {i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestApiLabel', { - defaultMessage: 'Ingest via API', - })} -

    - - } - value="ingestViaApi" - checked={selectedIngestMethod === 'ingestViaApi'} - onChange={() => setSelectedIngestMethod('ingestViaApi')} - > - - {i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestApiDescription', { - defaultMessage: - 'The most flexible way to index data, enabling full control over your customization and optimization options.', - })} - -
    - - -

    - {i18n.translate('searchApiPanels.welcomeBanner.ingestData.ingestIntegrationLabel', { - defaultMessage: 'Ingest via integration', - })} -

    - - } - value="ingestViaIntegration" - checked={selectedIngestMethod === 'ingestViaIntegration'} - onChange={() => setSelectedIngestMethod('ingestViaIntegration')} - > - - {i18n.translate( - 'searchApiPanels.welcomeBanner.ingestData.ingestIntegrationDescription', - { - defaultMessage: - 'Specialized ingestion tools optimized for transforming data and shipping it to Elasticsearch.', - } - )} - -
    -
    + +

    + {i18n.translate('searchApiPanels.welcomeBanner.ingestData.alternativeOptions', { + defaultMessage: 'Alternative ingestion options', + })} +

    +
    + + +
    ); }; diff --git a/packages/kbn-search-api-panels/components/ingestions_panel.tsx b/packages/kbn-search-api-panels/components/ingestions_panel.tsx new file mode 100644 index 000000000000..ef9a0ef95ad0 --- /dev/null +++ b/packages/kbn-search-api-panels/components/ingestions_panel.tsx @@ -0,0 +1,131 @@ +/* + * 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 { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiSpacer, EuiText, EuiLink } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { GithubLink } from './github_link'; + +interface IngestionPanelProps { + additionalIngestionPanel?: React.ReactNode; + docLinks: { beats: string; logstash: string }; + assetBasePath: string; +} + +export const IngestionsPanel: React.FC = ({ + additionalIngestionPanel, + docLinks, + assetBasePath, +}) => { + const panels = [ + { + description: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.logstashDescription', + { + defaultMessage: + 'General-purpose data processing pipeline for Elasticsearch. Use Logstash to extract and transform data from a variety of inputs and outputs.', + } + ), + title: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.logstashTitle', + { + defaultMessage: 'Logstash', + } + ), + links: [ + { + href: docLinks.logstash, + label: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.logstashDocumentationLabel', + { + defaultMessage: 'Documentation', + } + ), + }, + { + href: 'https://github.com/elastic/logstash', + isGithubLink: true, + label: 'logstash', + }, + ], + }, + { + description: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.beatsDescription', + { + defaultMessage: + 'Lightweight, single-purpose data shippers for Elasticsearch. Use Beats to send operational data from your servers.', + } + ), + title: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.beatsTitle', + { + defaultMessage: 'Beats', + } + ), + links: [ + { + href: docLinks.beats, + label: i18n.translate( + 'searchApiPanels.welcomeBanner.ingestData.alternativeOptions.beatsDocumentationLabel', + { + defaultMessage: 'Documentation', + } + ), + }, + { + href: 'https://github.com/elastic/beats', + isGithubLink: true, + label: 'beats', + }, + ], + }, + ]; + return ( + <> + {additionalIngestionPanel} + {panels.map(({ title, description, links }, panelIndex) => ( + + + +
    {title}
    +
    + + +

    {description}

    +
    +
    + {links && links.length > 0 && ( + <> + + {links.map(({ label, href, isGithubLink }, linksIndex) => ( + + {isGithubLink ? ( + + ) : ( + + {label} + + )} + + ))} + + + + )} +
    + ))} + + ); +}; diff --git a/packages/kbn-search-api-panels/components/integrations_panel.tsx b/packages/kbn-search-api-panels/components/integrations_panel.tsx deleted file mode 100644 index 3f6005f26ceb..000000000000 --- a/packages/kbn-search-api-panels/components/integrations_panel.tsx +++ /dev/null @@ -1,168 +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 { - EuiThemeProvider, - EuiPanel, - EuiFlexGroup, - EuiFlexItem, - EuiIcon, - EuiTitle, - EuiSpacer, - EuiText, - EuiLink, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { LEARN_MORE_LABEL } from '../constants'; -import { GithubLink } from './github_link'; - -export interface IntegrationsPanelProps { - docLinks: { beats: string; connectors: string; logstash: string }; - assetBasePath: string; -} - -export const IntegrationsPanel: React.FC = ({ - docLinks, - assetBasePath, -}) => { - return ( - - - - - - - - -

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

    -
    - - -

    - {i18n.translate('searchApiPanels.welcomeBanner.ingestData.logstashDescription', { - defaultMessage: - 'Add data to your data stream or index to make it searchable. Choose an ingestion method that fits your application and workflow.', - })} -

    -
    - - - - - - {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} - - - - - - - -
    -
    - - - - - - - -

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

    -
    - - - {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} - - - - - - - -
    -
    -
    -
    - ); -}; diff --git a/packages/kbn-search-api-panels/index.tsx b/packages/kbn-search-api-panels/index.tsx index 059aaf184ebf..7372e381c576 100644 --- a/packages/kbn-search-api-panels/index.tsx +++ b/packages/kbn-search-api-panels/index.tsx @@ -14,7 +14,7 @@ import { AuthenticatedUser } from '@kbn/security-plugin/common'; export * from './components/code_box'; export * from './components/github_link'; export * from './components/ingest_data'; -export * from './components/integrations_panel'; +export * from './components/ingestions_panel'; export * from './components/language_client_panel'; export * from './components/overview_panel'; export * from './components/select_client'; diff --git a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx index f0b5931e5443..9eab42f5cec7 100644 --- a/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/field_value_wildcard/index.test.tsx @@ -14,7 +14,7 @@ import { AutocompleteFieldWildcardComponent } from '.'; import { useFieldValueAutocomplete } from '../hooks/use_field_value_autocomplete'; import { fields, getField } from '../fields/index.mock'; import { autocompleteStartMock } from '../autocomplete/index.mock'; -import { FILENAME_WILDCARD_WARNING, FILEPATH_WARNING } from '@kbn/securitysolution-utils'; +import { WILDCARD_WARNING, FILEPATH_WARNING } from '@kbn/securitysolution-utils'; jest.mock('../hooks/use_field_value_autocomplete'); jest.mock('../translations', () => ({ @@ -368,7 +368,7 @@ describe('AutocompleteFieldWildcardComponent', () => { placeholder="Placeholder text" selectedField={getField('file.path.text')} selectedValue="invalid path" - warning={FILENAME_WILDCARD_WARNING} + warning={WILDCARD_WARNING} /> ); @@ -384,7 +384,7 @@ describe('AutocompleteFieldWildcardComponent', () => { const helpText = wrapper .find('[data-test-subj="valuesAutocompleteWildcardLabel"] div.euiFormHelpText') .at(0); - expect(helpText.text()).toEqual(FILENAME_WILDCARD_WARNING); + expect(helpText.text()).toEqual(WILDCARD_WARNING); expect(helpText.find('.euiToolTipAnchor')).toBeTruthy(); }); test('should show the warning helper text if the new value contains spaces when change', async () => { @@ -412,7 +412,7 @@ describe('AutocompleteFieldWildcardComponent', () => { placeholder="Placeholder text" selectedField={getField('file.path.text')} selectedValue="invalid path" - warning={FILENAME_WILDCARD_WARNING} + warning={WILDCARD_WARNING} /> ); diff --git a/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx b/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx index 3595b96d7e42..954b14a8ea24 100644 --- a/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx +++ b/packages/kbn-securitysolution-autocomplete/src/operator/index.test.tsx @@ -223,6 +223,7 @@ describe('operator', () => { { label: 'is one of' }, { label: 'is not one of' }, { label: 'matches' }, + { label: 'does not match' }, ]); }); diff --git a/packages/kbn-securitysolution-list-utils/src/autocomplete_operators/index.ts b/packages/kbn-securitysolution-list-utils/src/autocomplete_operators/index.ts index f9caa6387e35..c236cacad6a2 100644 --- a/packages/kbn-securitysolution-list-utils/src/autocomplete_operators/index.ts +++ b/packages/kbn-securitysolution-list-utils/src/autocomplete_operators/index.ts @@ -109,6 +109,7 @@ export const EVENT_FILTERS_OPERATORS: OperatorOption[] = [ isOneOfOperator, isNotOneOfOperator, matchesOperator, + doesNotMatchOperator, ]; /* diff --git a/packages/kbn-securitysolution-utils/src/path_validations/index.test.ts b/packages/kbn-securitysolution-utils/src/path_validations/index.test.ts index 5bb84816b160..f877683caec1 100644 --- a/packages/kbn-securitysolution-utils/src/path_validations/index.test.ts +++ b/packages/kbn-securitysolution-utils/src/path_validations/index.test.ts @@ -11,11 +11,43 @@ import { hasSimpleExecutableName, OperatingSystem, ConditionEntryField, + validatePotentialWildcardInput, validateFilePathInput, - FILENAME_WILDCARD_WARNING, + validateWildcardInput, + WILDCARD_WARNING, FILEPATH_WARNING, } from '.'; +describe('validatePotentialWildcardInput', () => { + it('warns on wildcard when field is file.path.text', () => { + expect( + validatePotentialWildcardInput({ + field: 'file.path.text', + os: OperatingSystem.WINDOWS, + value: 'c:\\path*.exe', + }) + ).toEqual(WILDCARD_WARNING); + }); + it('warns on wildcard when field is not file.path.text', () => { + expect( + validatePotentialWildcardInput({ + field: 'event.category', + os: OperatingSystem.WINDOWS, + value: 'some*value', + }) + ).toEqual(WILDCARD_WARNING); + }); +}); + +describe('validateWildcardInput', () => { + it('warns on wildcard for fields that are not file paths', () => { + expect(validateWildcardInput('*')).toEqual(WILDCARD_WARNING); + }); + it('does not warn if no wildcard', () => { + expect(validateWildcardInput('non-wildcard')).toEqual(undefined); + }); +}); + describe('validateFilePathInput', () => { describe('windows', () => { const os = OperatingSystem.WINDOWS; @@ -36,15 +68,13 @@ describe('validateFilePathInput', () => { }); it('warns on wildcard in file name at the end of the path', () => { - expect(validateFilePathInput({ os, value: 'c:\\path*.exe' })).toEqual( - FILENAME_WILDCARD_WARNING - ); + expect(validateFilePathInput({ os, value: 'c:\\path*.exe' })).toEqual(WILDCARD_WARNING); expect( validateFilePathInput({ os, value: 'C:\\Windows\\*\\FILENAME.EXE-*.gz', }) - ).toEqual(FILENAME_WILDCARD_WARNING); + ).toEqual(WILDCARD_WARNING); }); it('warns on unix paths or non-windows paths', () => { @@ -65,20 +95,23 @@ describe('validateFilePathInput', () => { : OperatingSystem.LINUX; it('does not warn on valid filenames', () => { - expect(validateFilePathInput({ os, value: '/opt/*/FILENAME.EXE-1231205124.gz' })).not.toEqual( - FILENAME_WILDCARD_WARNING - ); + expect( + validateFilePathInput({ + os, + value: '/opt/*/FILENAME.EXE-1231205124.gz', + }) + ).not.toEqual(WILDCARD_WARNING); expect( validateFilePathInput({ os, value: "/opt/*/test$ as2@13---12!@#A,DS.#$^&$!#~ 'as'd.华语.txt", }) - ).not.toEqual(FILENAME_WILDCARD_WARNING); + ).not.toEqual(WILDCARD_WARNING); }); it('warns on wildcard in file name at the end of the path', () => { - expect(validateFilePathInput({ os, value: '/opt/bin*' })).toEqual(FILENAME_WILDCARD_WARNING); + expect(validateFilePathInput({ os, value: '/opt/bin*' })).toEqual(WILDCARD_WARNING); expect(validateFilePathInput({ os, value: '/opt/FILENAME.EXE-*.gz' })).toEqual( - FILENAME_WILDCARD_WARNING + WILDCARD_WARNING ); }); diff --git a/packages/kbn-securitysolution-utils/src/path_validations/index.ts b/packages/kbn-securitysolution-utils/src/path_validations/index.ts index ac7c17426e72..b2ae2d9fbceb 100644 --- a/packages/kbn-securitysolution-utils/src/path_validations/index.ts +++ b/packages/kbn-securitysolution-utils/src/path_validations/index.ts @@ -8,8 +8,8 @@ import { i18n } from '@kbn/i18n'; -export const FILENAME_WILDCARD_WARNING = i18n.translate('utils.filename.wildcardWarning', { - defaultMessage: `Using wildcards in file paths can impact Endpoint performance`, +export const WILDCARD_WARNING = i18n.translate('utils.wildcardWarning', { + defaultMessage: `Using wildcards can impact Endpoint performance`, }); export const FILEPATH_WARNING = i18n.translate('utils.filename.pathWarning', { @@ -52,39 +52,60 @@ export enum OperatingSystem { export type EntryTypes = 'match' | 'wildcard' | 'match_any'; export type TrustedAppEntryTypes = Extract; -export const validateFilePathInput = ({ +export const validatePotentialWildcardInput = ({ + field = '', os, value = '', }: { + field?: string; os: OperatingSystem; value?: string; }): string | undefined => { const textInput = value.trim(); + if (field === 'file.path.text') { + return validateFilePathInput({ os, value: textInput }); + } + return validateWildcardInput(textInput); +}; + +export const validateFilePathInput = ({ + os, + value, +}: { + os: OperatingSystem; + value: string; +}): string | undefined => { const isValidFilePath = isPathValid({ os, field: 'file.path.text', type: 'wildcard', - value: textInput, + value, }); const hasSimpleFileName = hasSimpleExecutableName({ os, type: 'wildcard', - value: textInput, + value, }); - if (!textInput.length) { + if (!value.length) { return FILEPATH_WARNING; } if (isValidFilePath) { if (hasSimpleFileName !== undefined && !hasSimpleFileName) { - return FILENAME_WILDCARD_WARNING; + return WILDCARD_WARNING; } } else { return FILEPATH_WARNING; } }; +export const validateWildcardInput = (value?: string): string | undefined => { + if (/[*?]/.test(value ?? '')) { + return WILDCARD_WARNING; + } +}; + export const hasSimpleExecutableName = ({ os, type, diff --git a/packages/kbn-server-http-tools/index.ts b/packages/kbn-server-http-tools/index.ts index 3e172297bf6c..a572cc6ab083 100644 --- a/packages/kbn-server-http-tools/index.ts +++ b/packages/kbn-server-http-tools/index.ts @@ -10,6 +10,7 @@ export type { IHttpConfig, ISslConfig, ICorsConfig } from './src/types'; export { createServer } from './src/create_server'; export { defaultValidationErrorHandler } from './src/default_validation_error_handler'; export { getListenerOptions } from './src/get_listener_options'; -export { getServerOptions } from './src/get_server_options'; +export { getServerOptions, getServerTLSOptions } from './src/get_server_options'; export { getRequestId } from './src/get_request_id'; +export { setTlsConfig } from './src/set_tls_config'; export { sslSchema, SslConfig } from './src/ssl'; diff --git a/packages/kbn-server-http-tools/src/get_server_options.ts b/packages/kbn-server-http-tools/src/get_server_options.ts index ade90a0e0d3f..5cac081fdd14 100644 --- a/packages/kbn-server-http-tools/src/get_server_options.ts +++ b/packages/kbn-server-http-tools/src/get_server_options.ts @@ -9,7 +9,7 @@ import { RouteOptionsCors, ServerOptions } from '@hapi/hapi'; import { ServerOptions as TLSOptions } from 'https'; import { defaultValidationErrorHandler } from './default_validation_error_handler'; -import { IHttpConfig } from './types'; +import { IHttpConfig, ISslConfig } from './types'; const corsAllowedHeaders = ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf']; @@ -50,26 +50,31 @@ export function getServerOptions(config: IHttpConfig, { configureTLS = true } = }, }; - if (configureTLS && config.ssl.enabled) { - const ssl = config.ssl; - - // TODO: Hapi types have a typo in `tls` property type definition: `https.RequestOptions` is used instead of - // `https.ServerOptions`, and `honorCipherOrder` isn't presented in `https.RequestOptions`. - const tlsOptions: TLSOptions = { - ca: ssl.certificateAuthorities, - cert: ssl.certificate, - ciphers: config.ssl.cipherSuites?.join(':'), - // We use the server's cipher order rather than the client's to prevent the BEAST attack. - honorCipherOrder: true, - key: ssl.key, - passphrase: ssl.keyPassphrase, - secureOptions: ssl.getSecureOptions ? ssl.getSecureOptions() : undefined, - requestCert: ssl.requestCert, - rejectUnauthorized: ssl.rejectUnauthorized, - }; - - options.tls = tlsOptions; + if (configureTLS) { + options.tls = getServerTLSOptions(config.ssl); } return options; } + +/** + * Converts Kibana `SslConfig` into `TLSOptions` that are accepted by the Hapi server, + * and by https.Server.setSecureContext() + */ +export function getServerTLSOptions(ssl: ISslConfig): TLSOptions | undefined { + if (!ssl.enabled) { + return undefined; + } + return { + ca: ssl.certificateAuthorities, + cert: ssl.certificate, + ciphers: ssl.cipherSuites?.join(':'), + // We use the server's cipher order rather than the client's to prevent the BEAST attack. + honorCipherOrder: true, + key: ssl.key, + passphrase: ssl.keyPassphrase, + secureOptions: ssl.getSecureOptions ? ssl.getSecureOptions() : undefined, + requestCert: ssl.requestCert, + rejectUnauthorized: ssl.rejectUnauthorized, + }; +} diff --git a/packages/kbn-subscription-tracking/index.ts b/packages/kbn-server-http-tools/src/set_tls_config.test.mocks.ts similarity index 59% rename from packages/kbn-subscription-tracking/index.ts rename to packages/kbn-server-http-tools/src/set_tls_config.test.mocks.ts index de17c595918d..4b93301b334e 100644 --- a/packages/kbn-subscription-tracking/index.ts +++ b/packages/kbn-server-http-tools/src/set_tls_config.test.mocks.ts @@ -6,12 +6,12 @@ * Side Public License, v 1. */ -export * from './src/subscription_elements'; +export const getServerTLSOptionsMock = jest.fn(); -export { - SubscriptionTrackingContext, - SubscriptionTrackingProvider, - registerEvents, -} from './src/services'; - -export * from './types'; +jest.doMock('./get_server_options', () => { + const actual = jest.requireActual('./get_server_options'); + return { + ...actual, + getServerTLSOptions: getServerTLSOptionsMock, + }; +}); diff --git a/packages/kbn-server-http-tools/src/set_tls_config.test.ts b/packages/kbn-server-http-tools/src/set_tls_config.test.ts new file mode 100644 index 000000000000..ea3e61c13944 --- /dev/null +++ b/packages/kbn-server-http-tools/src/set_tls_config.test.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { getServerTLSOptionsMock } from './set_tls_config.test.mocks'; +import { Server } from '@hapi/hapi'; +import type { ISslConfig } from './types'; +import { setTlsConfig } from './set_tls_config'; + +describe('setTlsConfig', () => { + beforeEach(() => { + getServerTLSOptionsMock.mockReset(); + getServerTLSOptionsMock.mockReturnValue({}); + }); + + it('throws when called for a non-TLS server', () => { + const server = new Server({}); + const config: ISslConfig = { enabled: true }; + expect(() => setTlsConfig(server, config)).toThrowErrorMatchingInlineSnapshot( + `"tried to set TLS config on a non-TLS http server"` + ); + }); + + it('calls `getServerTLSOptions` with the correct parameters', () => { + const server = new Server({}); + // easiest way to shim a tls.Server + (server.listener as any).setSecureContext = jest.fn(); + const config: ISslConfig = { enabled: true }; + + setTlsConfig(server, config); + + expect(getServerTLSOptionsMock).toHaveBeenCalledTimes(1); + expect(getServerTLSOptionsMock).toHaveBeenCalledWith(config); + }); + + it('throws when called for a disabled SSL config', () => { + const server = new Server({}); + // easiest way to shim a tls.Server + (server.listener as any).setSecureContext = jest.fn(); + const config: ISslConfig = { enabled: false }; + + getServerTLSOptionsMock.mockReturnValue(undefined); + + expect(() => setTlsConfig(server, config)).toThrowErrorMatchingInlineSnapshot( + `"tried to apply a disabled SSL config"` + ); + }); + + it('calls `setSecureContext` on the underlying server', () => { + const server = new Server({}); + // easiest way to shim a tls.Server + const setSecureContextMock = jest.fn(); + (server.listener as any).setSecureContext = setSecureContextMock; + const config: ISslConfig = { enabled: true }; + + const tlsConfig = { someTlsConfig: true }; + getServerTLSOptionsMock.mockReturnValue(tlsConfig); + + setTlsConfig(server, config); + + expect(setSecureContextMock).toHaveBeenCalledTimes(1); + expect(setSecureContextMock).toHaveBeenCalledWith(tlsConfig); + }); +}); diff --git a/packages/kbn-server-http-tools/src/set_tls_config.ts b/packages/kbn-server-http-tools/src/set_tls_config.ts new file mode 100644 index 000000000000..1f2e1d70fa12 --- /dev/null +++ b/packages/kbn-server-http-tools/src/set_tls_config.ts @@ -0,0 +1,29 @@ +/* + * 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 { Server as HapiServer } from '@hapi/hapi'; +import type { Server as HttpServer } from 'http'; +import type { Server as TlsServer } from 'https'; +import type { ISslConfig } from './types'; +import { getServerTLSOptions } from './get_server_options'; + +function isServerTLS(server: HttpServer): server is TlsServer { + return 'setSecureContext' in server; +} + +export const setTlsConfig = (hapiServer: HapiServer, sslConfig: ISslConfig) => { + const server = hapiServer.listener; + if (!isServerTLS(server)) { + throw new Error('tried to set TLS config on a non-TLS http server'); + } + const tlsOptions = getServerTLSOptions(sslConfig); + if (!tlsOptions) { + throw new Error('tried to apply a disabled SSL config'); + } + server.setSecureContext(tlsOptions); +}; diff --git a/packages/kbn-server-http-tools/src/ssl/ssl_config.test.ts b/packages/kbn-server-http-tools/src/ssl/ssl_config.test.ts index 112fcd8a449f..c6f701ef67a1 100644 --- a/packages/kbn-server-http-tools/src/ssl/ssl_config.test.ts +++ b/packages/kbn-server-http-tools/src/ssl/ssl_config.test.ts @@ -164,6 +164,79 @@ describe('#SslConfig', () => { expect(configValue.certificate).toEqual('content-of-another-path'); }); }); + + describe('isEqualTo()', () => { + const createEnabledConfig = (obj: any) => + createConfig({ + enabled: true, + key: 'same-key', + certificate: 'same-cert', + ...obj, + }); + + it('compares `enabled`', () => { + const reference = createConfig({ enabled: true, key: 'same-key', certificate: 'same-cert' }); + const same = createConfig({ enabled: true, key: 'same-key', certificate: 'same-cert' }); + const different = createConfig({ enabled: false, key: 'same-key', certificate: 'same-cert' }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `key`', () => { + const reference = createEnabledConfig({ key: 'keyA', certificate: 'same-cert' }); + const same = createEnabledConfig({ key: 'keyA', certificate: 'same-cert' }); + const different = createEnabledConfig({ key: 'keyB', certificate: 'same-cert' }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `keyPassphrase`', () => { + const reference = createEnabledConfig({ keyPassphrase: 'passA' }); + const same = createEnabledConfig({ keyPassphrase: 'passA' }); + const different = createEnabledConfig({ keyPassphrase: 'passB' }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `certificate`', () => { + const reference = createEnabledConfig({ key: 'same-key', certificate: 'cert-a' }); + const same = createEnabledConfig({ key: 'same-key', certificate: 'cert-a' }); + const different = createEnabledConfig({ key: 'same-key', certificate: 'cert-b' }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `cipherSuites`', () => { + const reference = createEnabledConfig({ cipherSuites: ['A', 'B'] }); + const same = createEnabledConfig({ cipherSuites: ['A', 'B'] }); + const different = createEnabledConfig({ cipherSuites: ['A', 'C'] }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `supportedProtocols`', () => { + const reference = createEnabledConfig({ supportedProtocols: ['TLSv1.1', 'TLSv1.2'] }); + const same = createEnabledConfig({ supportedProtocols: ['TLSv1.1', 'TLSv1.2'] }); + const different = createEnabledConfig({ supportedProtocols: ['TLSv1.1', 'TLSv1.3'] }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + + it('compares `clientAuthentication`', () => { + const reference = createEnabledConfig({ clientAuthentication: 'none' }); + const same = createEnabledConfig({ clientAuthentication: 'none' }); + const different = createEnabledConfig({ clientAuthentication: 'required' }); + + expect(reference.isEqualTo(same)).toBe(true); + expect(reference.isEqualTo(different)).toBe(false); + }); + }); }); describe('#sslSchema', () => { diff --git a/packages/kbn-server-http-tools/src/ssl/ssl_config.ts b/packages/kbn-server-http-tools/src/ssl/ssl_config.ts index 53d3616a09a7..a5d43064baa6 100644 --- a/packages/kbn-server-http-tools/src/ssl/ssl_config.ts +++ b/packages/kbn-server-http-tools/src/ssl/ssl_config.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import { isEqual } from 'lodash'; import { schema, TypeOf } from '@kbn/config-schema'; import { readPkcs12Keystore, readPkcs12Truststore } from '@kbn/crypto'; import { constants as cryptoConstants } from 'crypto'; @@ -161,6 +162,13 @@ export class SslConfig { : secureOptions | secureOption; // eslint-disable-line no-bitwise }, 0); } + + public isEqualTo(otherConfig: SslConfig) { + if (this === otherConfig) { + return true; + } + return isEqual(this, otherConfig); + } } const readFile = (file: string) => readFileSync(file, 'utf8'); diff --git a/packages/kbn-subscription-tracking/README.md b/packages/kbn-subscription-tracking/README.md deleted file mode 100644 index 4f8459398088..000000000000 --- a/packages/kbn-subscription-tracking/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# @kbn/subscription-tracking - -This package leverages the `@kbn/analytics-client` package to send dedicated subscription tracking events. - -It provides a set of React components that automatically track `impression` and `click` events. Consumers of those components need to specify a `subscription context` that gives more details on the type of feature that is advertised and the location of the upsell. - -```typescript -import { SubscriptionLink } from '@kbn/subscription-tracking'; -import type { SubscriptionContext } from '@kbn/subscription-tracking'; - -const subscriptionContext: SubscriptionContext = { - feature: 'threat-intelligence', - source: 'security__threat-intelligence', -}; - -export const Paywall = () => { - return ( -
    - - Upgrade to Platinum to get this feature - -
    - ); -}; -``` - -The example above uses a `SubscriptionLink` which is a wrapper of `EuiLink` . So it behaves just like a normal link. Alternatively, upsells can also use a `SubscriptionButton` or `SubscriptionButtonEmpty` which wrap `EuiButton` and `EuiButtonEmpty` respectively. - -When the link is mounted, it will send off an `impression` event with the given `subscriptionContext`. That piece of metadata consists of an identifier of the advertised feature (in this case `threat-intelligence`) and the `source` (aka location) of the impression (in this case the `threat-intelligence` page in the `security` solution). `source` follows the following format: `{solution-identifier}__location-identifier`. - -There are no special rules for how to name these identifiers but it's good practise to make sure that `feature` has the same value for all upsells advertising the same feature (e.g. use enums for features to prevent spelling mistakes). - -Upon interaction with the upsell link/button, a special `click` event is sent, which, again, contains the same subscription context. - -If you want to use the `subscription-tracking` elements in your app, you have to set up a `SubscriptionTrackingProvider` in your plugin setup and register the tracking events on startup. Have a look at https://github.com/elastic/kibana/pull/143910 for an example of an integration. diff --git a/packages/kbn-subscription-tracking/kibana.jsonc b/packages/kbn-subscription-tracking/kibana.jsonc deleted file mode 100644 index e165baebfa76..000000000000 --- a/packages/kbn-subscription-tracking/kibana.jsonc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "shared-common", - "id": "@kbn/subscription-tracking", - "owner": "@elastic/security-threat-hunting-investigations" -} diff --git a/packages/kbn-subscription-tracking/mocks.tsx b/packages/kbn-subscription-tracking/mocks.tsx deleted file mode 100644 index b918f9bba282..000000000000 --- a/packages/kbn-subscription-tracking/mocks.tsx +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 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, { FC } from 'react'; -import { analyticsClientMock } from '@kbn/analytics-client/src/mocks'; - -import { SubscriptionTrackingProvider } from './src/services'; - -const analyticsClientMockInst = analyticsClientMock.create(); - -/** - * Mock for the external services provider. Only use in tests! - */ -export const MockSubscriptionTrackingProvider: FC = ({ children }) => { - return ( - - {children} - - ); -}; diff --git a/packages/kbn-subscription-tracking/src/helpers.test.ts b/packages/kbn-subscription-tracking/src/helpers.test.ts deleted file mode 100644 index fa000567d35d..000000000000 --- a/packages/kbn-subscription-tracking/src/helpers.test.ts +++ /dev/null @@ -1,45 +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 { isValidContext } from './helpers'; - -describe('tracking', () => { - describe('isValidLocation', () => { - it('identifies correct contexts', () => { - expect( - isValidContext({ - feature: 'test', - source: 'security__test', - }) - ).toBeTruthy(); - }); - - it('identifies incorrect contexts', () => { - expect( - isValidContext({ - feature: '', - source: 'security__', - }) - ).toBeFalsy(); - - expect( - isValidContext({ - feature: 'test', - source: 'security__', - }) - ).toBeFalsy(); - - expect( - isValidContext({ - feature: '', - source: 'security__test', - }) - ).toBeFalsy(); - }); - }); -}); diff --git a/packages/kbn-subscription-tracking/src/services.tsx b/packages/kbn-subscription-tracking/src/services.tsx deleted file mode 100644 index 857bd0b0dcd8..000000000000 --- a/packages/kbn-subscription-tracking/src/services.tsx +++ /dev/null @@ -1,70 +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, { FC, useContext } from 'react'; -import type { AnalyticsClient, EventTypeOpts } from '@kbn/analytics-client'; -import { EVENT_NAMES, Services, SubscriptionContextData } from '../types'; - -export const SubscriptionTrackingContext = React.createContext(null); - -/** - * External services provider - */ -export const SubscriptionTrackingProvider: FC = ({ children, ...services }) => { - return ( - - {children} - - ); -}; - -/** - * React hook for accessing pre-wired services. - */ -export function useServices() { - const context = useContext(SubscriptionTrackingContext); - - if (!context) { - throw new Error( - 'SubscriptionTrackingContext is missing. Ensure your component or React root is wrapped with SubscriptionTrackingProvider.' - ); - } - - return context; -} - -const subscriptionContextSchema: EventTypeOpts['schema'] = { - source: { - type: 'keyword', - _meta: { - description: - 'A human-readable identifier describing the location of the beginning of the subscription flow', - }, - }, - feature: { - type: 'keyword', - _meta: { - description: 'A human-readable identifier describing the feature that is being promoted', - }, - }, -}; - -/** - * Registers the subscription-specific event types - */ -export function registerEvents(analyticsClient: Pick) { - analyticsClient.registerEventType({ - eventType: EVENT_NAMES.IMPRESSION, - schema: subscriptionContextSchema, - }); - - analyticsClient.registerEventType({ - eventType: EVENT_NAMES.CLICK, - schema: subscriptionContextSchema, - }); -} diff --git a/packages/kbn-subscription-tracking/src/subscription_elements.test.tsx b/packages/kbn-subscription-tracking/src/subscription_elements.test.tsx deleted file mode 100644 index 1795bbf42dd0..000000000000 --- a/packages/kbn-subscription-tracking/src/subscription_elements.test.tsx +++ /dev/null @@ -1,108 +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 { render, screen } from '@testing-library/react'; -import { - SubscriptionLink, - SubscriptionButton, - SubscriptionButtonEmpty, -} from './subscription_elements'; -import { SubscriptionTrackingProvider } from './services'; -import { EVENT_NAMES, Services, SubscriptionContextData } from '../types'; -import { coolDownTimeMs, resetCoolDown } from './use_impression'; - -const testServices: Services = { - navigateToApp: jest.fn(), - analyticsClient: { - reportEvent: jest.fn(), - registerEventType: jest.fn(), - } as any, -}; -const testContext: SubscriptionContextData = { feature: 'test', source: 'security__test' }; - -const WithProviders: React.FC = ({ children }) => ( - - {children} - -); - -const renderWithProviders = (children: React.ReactElement) => - render(children, { wrapper: WithProviders }); - -const reset = () => { - jest.resetAllMocks(); - resetCoolDown(); -}; - -describe('SubscriptionElements', () => { - beforeAll(() => { - jest.useFakeTimers(); - }); - - afterAll(() => { - jest.useRealTimers(); - }); - - [SubscriptionButton, SubscriptionLink, SubscriptionButtonEmpty].forEach((SubscriptionElement) => { - describe(SubscriptionElement.name, () => { - beforeEach(reset); - - it('renders the children correctly', () => { - renderWithProviders( - Hello - ); - expect(screen.getByText('Hello')).toBeTruthy(); - }); - - it('fires an impression event when rendered', () => { - renderWithProviders(); - expect(testServices.analyticsClient.reportEvent).toHaveBeenCalledWith( - EVENT_NAMES.IMPRESSION, - testContext - ); - }); - - it('fires an impression event when rendered (but only once)', () => { - const { unmount } = renderWithProviders( - - ); - expect(testServices.analyticsClient.reportEvent).toHaveBeenCalledTimes(1); - unmount(); - - // does not create an impression again when remounted - const { unmount: unmountAgain } = renderWithProviders( - - ); - unmountAgain(); - expect(testServices.analyticsClient.reportEvent).toHaveBeenCalledTimes(1); - - // only creates anew impression when the cooldown time has passed - jest.setSystemTime(Date.now() + coolDownTimeMs); - renderWithProviders(); - expect(testServices.analyticsClient.reportEvent).toHaveBeenCalledTimes(2); - }); - - it('tracks a click when clicked and navigates to page', () => { - renderWithProviders( - hello - ); - - screen.getByText('hello').click(); - expect(testServices.analyticsClient.reportEvent).toHaveBeenCalledWith( - EVENT_NAMES.CLICK, - testContext - ); - expect(testServices.navigateToApp).toHaveBeenCalled(); - }); - }); - }); -}); diff --git a/packages/kbn-subscription-tracking/src/subscription_elements.tsx b/packages/kbn-subscription-tracking/src/subscription_elements.tsx deleted file mode 100644 index f29c58d8a0a4..000000000000 --- a/packages/kbn-subscription-tracking/src/subscription_elements.tsx +++ /dev/null @@ -1,79 +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 { EuiLink, EuiButton, EuiButtonEmpty } from '@elastic/eui'; -import type { EuiLinkProps, EuiButtonEmptyProps, EuiButtonProps } from '@elastic/eui'; -import { useGoToSubscription } from './use_go_to_subscription'; -import { useImpression } from './use_impression'; -import type { SubscriptionContextData } from '../types'; - -interface CommonProps { - /** The context information for this subscription element */ - subscriptionContext: SubscriptionContextData; -} - -export type SubscriptionLinkProps = EuiLinkProps & CommonProps; - -/** - * Wrapper around `EuiLink` that provides subscription events - */ -export function SubscriptionLink({ - subscriptionContext, - children, - ...restProps -}: SubscriptionLinkProps) { - const goToSubscription = useGoToSubscription({ subscriptionContext }); - useImpression(subscriptionContext); - - return ( - - {children} - - ); -} - -export type SubscriptionButtonProps = EuiButtonProps & CommonProps; - -/** - * Wrapper around `EuiButton` that provides subscription events - */ -export function SubscriptionButton({ - subscriptionContext, - children, - ...restProps -}: SubscriptionButtonProps) { - const goToSubscription = useGoToSubscription({ subscriptionContext }); - useImpression(subscriptionContext); - - return ( - - {children} - - ); -} - -export type SubscriptionButtonEmptyProps = EuiButtonEmptyProps & CommonProps; - -/** - * Wrapper around `EuiButtonEmpty` that provides subscription events - */ -export function SubscriptionButtonEmpty({ - subscriptionContext, - children, - ...restProps -}: SubscriptionButtonEmptyProps) { - const goToSubscription = useGoToSubscription({ subscriptionContext }); - useImpression(subscriptionContext); - - return ( - - {children} - - ); -} diff --git a/packages/kbn-subscription-tracking/src/use_go_to_subscription.ts b/packages/kbn-subscription-tracking/src/use_go_to_subscription.ts deleted file mode 100644 index 6c93fb27ee9b..000000000000 --- a/packages/kbn-subscription-tracking/src/use_go_to_subscription.ts +++ /dev/null @@ -1,35 +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 { useCallback } from 'react'; -import { isValidContext } from './helpers'; -import { useServices } from './services'; -import { EVENT_NAMES, SubscriptionContextData } from '../types'; - -interface Options { - subscriptionContext: SubscriptionContextData; -} - -/** - * Provides a navigation function that navigates to the subscription - * management page. When the function executes, a click event with the - * given context is emitted. - */ -export const useGoToSubscription = ({ subscriptionContext }: Options) => { - const { navigateToApp, analyticsClient } = useServices(); - const goToSubscription = useCallback(() => { - if (isValidContext(subscriptionContext)) { - analyticsClient.reportEvent(EVENT_NAMES.CLICK, subscriptionContext); - } else { - // eslint-disable-next-line no-console - console.error('The provided subscription context is invalid', subscriptionContext); - } - navigateToApp('management', { path: 'stack/license_management' }); - }, [analyticsClient, navigateToApp, subscriptionContext]); - - return goToSubscription; -}; diff --git a/packages/kbn-subscription-tracking/src/use_impression.ts b/packages/kbn-subscription-tracking/src/use_impression.ts deleted file mode 100644 index eb8aa4c2e0ec..000000000000 --- a/packages/kbn-subscription-tracking/src/use_impression.ts +++ /dev/null @@ -1,57 +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 { useEffect } from 'react'; -import { isValidContext } from './helpers'; -import { useServices } from './services'; -import { EVENT_NAMES, SubscriptionContextData } from '../types'; - -/** - * Sends an impression event with the given context. - * - * Note: impression events are throttled and will not fire more - * often than once every 30 seconds. - */ -export const useImpression = (context: SubscriptionContextData) => { - const { analyticsClient } = useServices(); - - useEffect(() => { - if (!isValidContext(context)) { - // eslint-disable-next-line no-console - console.error('The provided subscription context is invalid', context); - return; - } - if (!isCoolingDown(context)) { - analyticsClient.reportEvent(EVENT_NAMES.IMPRESSION, context); - coolDown(context); - } - }, [analyticsClient, context]); -}; - -/** - * Impressions from the same context should not fire more than once every 30 seconds. - * This prevents logging too many impressions in case a page is reloaded often or - * if the user is navigating back and forth rapidly. - */ -export const coolDownTimeMs = 30 * 1000; -let impressionCooldown = new WeakMap(); - -function isCoolingDown(context: SubscriptionContextData) { - const previousLog = impressionCooldown.get(context); - - // we logged before and we are in the cooldown period - return previousLog && Date.now() - previousLog < coolDownTimeMs; -} - -function coolDown(context: SubscriptionContextData) { - impressionCooldown.set(context, Date.now()); -} - -export function resetCoolDown() { - impressionCooldown = new WeakMap(); -} diff --git a/packages/kbn-subscription-tracking/tsconfig.json b/packages/kbn-subscription-tracking/tsconfig.json deleted file mode 100644 index 677e9db998bb..000000000000 --- a/packages/kbn-subscription-tracking/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "outDir": "target/types", - "types": ["jest", "node", "react"] - }, - "include": ["**/*.ts", "**/*.tsx"], - "exclude": ["target/**/*"], - "kbn_references": ["@kbn/analytics-client"] -} diff --git a/packages/kbn-subscription-tracking/types.ts b/packages/kbn-subscription-tracking/types.ts deleted file mode 100644 index a2adf0c6d90c..000000000000 --- a/packages/kbn-subscription-tracking/types.ts +++ /dev/null @@ -1,47 +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 type { AnalyticsClient } from '@kbn/analytics-client'; - -enum SolutionIdentifier { - observability = 'observability', - security = 'security', -} -type LocationString = string; -type SourceIdentifier = `${SolutionIdentifier}__${LocationString}`; -/** - * A piece of metadata which consists of an identifier of the advertised feature and - * the `source` (e.g. location) of the subscription element. - */ -export interface SubscriptionContextData { - /** - * A human-readable identifier describing the location of the beginning of the - * subscription flow. - * Location identifiers are prefixed with a solution identifier, e.g. `security__` - * - * @example "security__host-overview" - the user is looking at an upsell button - * on the host overview page in the security solution - */ - source: SourceIdentifier; - - /** - * A human-readable identifier describing the feature that is being promoted. - * - * @example "alerts-by-process-ancestry" - */ - feature: string; -} - -export interface Services { - navigateToApp: (app: string, options: { path: string }) => void; - analyticsClient: Pick; -} - -export enum EVENT_NAMES { - CLICK = 'subscription__upsell__click', - IMPRESSION = 'subscription__upsell__impression', -} diff --git a/packages/kbn-test/src/es/test_es_cluster.ts b/packages/kbn-test/src/es/test_es_cluster.ts index 461ad2b6f0df..84c2da1e52f8 100644 --- a/packages/kbn-test/src/es/test_es_cluster.ts +++ b/packages/kbn-test/src/es/test_es_cluster.ts @@ -71,7 +71,10 @@ export interface CreateTestEsClusterOptions { */ esArgs?: string[]; esFrom?: string; - esServerlessOptions?: Pick; + esServerlessOptions?: Pick< + ServerlessOptions, + 'image' | 'tag' | 'resources' | 'host' | 'kibanaUrl' + >; esJavaOpts?: string; /** * License to run your cluster under. Keep in mind that a `trial` license @@ -242,10 +245,7 @@ export function createTestEsCluster< await firstNode.runServerless({ basePath, esArgs: customEsArgs, - image: esServerlessOptions?.image, - tag: esServerlessOptions?.tag, - host: esServerlessOptions?.host, - resources: esServerlessOptions?.resources, + ...esServerlessOptions, port, clean: true, background: true, 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 742f729745d2..4f01321b8239 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts +++ b/packages/kbn-test/src/functional_tests/lib/run_elasticsearch.ts @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import Url from 'url'; import { resolve } from 'path'; import type { ToolingLog } from '@kbn/tooling-log'; import getPort from 'get-port'; @@ -160,7 +161,18 @@ async function startEsNode({ return cluster; } -function getESServerlessOptions(esServerlessImageFromArg: string | undefined, config: Config) { +interface EsServerlessOptions { + host?: string; + resources: string[]; + kibanaUrl: string; + tag?: string; + image?: string; +} + +function getESServerlessOptions( + esServerlessImageFromArg: string | undefined, + config: Config +): EsServerlessOptions { const esServerlessImageUrlOrTag = esServerlessImageFromArg || esTestConfig.getESServerlessImage() || @@ -172,24 +184,24 @@ function getESServerlessOptions(esServerlessImageFromArg: string | undefined, co const serverlessHost: string | undefined = config.has('esServerlessOptions.host') && config.get('esServerlessOptions.host'); + const commonOptions = { + host: serverlessHost, + resources: serverlessResources, + kibanaUrl: Url.format({ + protocol: config.get('servers.kibana.protocol'), + hostname: config.get('servers.kibana.hostname'), + port: config.get('servers.kibana.port'), + }), + }; + if (esServerlessImageUrlOrTag) { - if (esServerlessImageUrlOrTag.includes(':')) { - return { - resources: serverlessResources, - image: esServerlessImageUrlOrTag, - host: serverlessHost, - }; - } else { - return { - resources: serverlessResources, - tag: esServerlessImageUrlOrTag, - host: serverlessHost, - }; - } + return { + ...commonOptions, + ...(esServerlessImageUrlOrTag.includes(':') + ? { image: esServerlessImageUrlOrTag } + : { tag: esServerlessImageUrlOrTag }), + }; } - return { - resources: serverlessResources, - host: serverlessHost, - }; + return commonOptions; } diff --git a/packages/kbn-text-based-editor/src/editor_footer.tsx b/packages/kbn-text-based-editor/src/editor_footer.tsx index 5070e2d5789e..d31f731821bb 100644 --- a/packages/kbn-text-based-editor/src/editor_footer.tsx +++ b/packages/kbn-text-based-editor/src/editor_footer.tsx @@ -19,6 +19,8 @@ import { EuiPopoverTitle, EuiDescriptionList, EuiDescriptionListDescription, + EuiButton, + useEuiTheme, } from '@elastic/eui'; import { Interpolation, Theme, css } from '@emotion/react'; import { css as classNameCss } from '@emotion/css'; @@ -60,12 +62,14 @@ export function ErrorsWarningsPopover({ type, setIsPopoverOpen, onErrorClick, + isSpaceReduced, }: { isPopoverOpen: boolean; items: MonacoError[]; type: 'error' | 'warning'; setIsPopoverOpen: (flag: boolean) => void; onErrorClick: (error: MonacoError) => void; + isSpaceReduced?: boolean; }) { const strings = getConstsByType(type, items.length); return ( @@ -90,7 +94,7 @@ export function ErrorsWarningsPopover({ setIsPopoverOpen(!isPopoverOpen); }} > -

    {strings.message}

    +

    {isSpaceReduced ? items.length : strings.message}

    } ownFocus={false} @@ -151,8 +155,11 @@ interface EditorFooterProps { warning?: MonacoError[]; detectTimestamp: boolean; onErrorClick: (error: MonacoError) => void; - refreshErrors: () => void; + runQuery: () => void; hideRunQueryText?: boolean; + disableSubmitAction?: boolean; + editorIsInline?: boolean; + isSpaceReduced?: boolean; } export const EditorFooter = memo(function EditorFooter({ @@ -162,10 +169,15 @@ export const EditorFooter = memo(function EditorFooter({ warning, detectTimestamp, onErrorClick, - refreshErrors, + runQuery, hideRunQueryText, + disableSubmitAction, + editorIsInline, + isSpaceReduced, }: EditorFooterProps) { + const { euiTheme } = useEuiTheme(); const [isPopoverOpen, setIsPopoverOpen] = useState(false); + return ( - {errors && errors.length > 0 && ( - - )} - {warning && warning.length > 0 && ( - - )}

    @@ -206,23 +200,22 @@ export const EditorFooter = memo(function EditorFooter({ - - -

    - {detectTimestamp + {isSpaceReduced + ? '@timestamp' + : detectTimestamp ? i18n.translate( 'textBasedEditor.query.textBasedLanguagesEditor.timestampDetected', { - defaultMessage: '@timestamp detected', + defaultMessage: '@timestamp found', } ) : i18n.translate( 'textBasedEditor.query.textBasedLanguagesEditor.timestampNotDetected', { - defaultMessage: '@timestamp not detected', + defaultMessage: '@timestamp not found', } )}

    @@ -230,6 +223,26 @@ export const EditorFooter = memo(function EditorFooter({
    + {errors && errors.length > 0 && ( + + )} + {warning && warning.length > 0 && ( + + )}
    {!hideRunQueryText && ( @@ -255,6 +268,53 @@ export const EditorFooter = memo(function EditorFooter({ )} + {Boolean(editorIsInline) && ( + + + + + {isSpaceReduced + ? i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.run', { + defaultMessage: 'Run', + }) + : i18n.translate('textBasedEditor.query.textBasedLanguagesEditor.runQuery', { + defaultMessage: 'Run query', + })} + + + + {COMMAND_KEY}⏎ + + + + + + )} ); }); diff --git a/packages/kbn-text-based-editor/src/resizable_button.tsx b/packages/kbn-text-based-editor/src/resizable_button.tsx index fb4ee944bc2f..5a52d67780ca 100644 --- a/packages/kbn-text-based-editor/src/resizable_button.tsx +++ b/packages/kbn-text-based-editor/src/resizable_button.tsx @@ -13,11 +13,13 @@ import { css } from '@emotion/react'; export function ResizableButton({ onMouseDownResizeHandler, onKeyDownResizeHandler, + editorIsInline, }: { onMouseDownResizeHandler: ( mouseDownEvent: React.MouseEvent | React.TouchEvent ) => void; onKeyDownResizeHandler: (keyDownEvernt: React.KeyboardEvent) => void; + editorIsInline?: boolean; }) { return ( { let position = isCompactFocused ? ('absolute' as 'absolute') : ('relative' as 'relative'); // cast string to type 'relative' | 'absolute' if (isCodeEditorExpanded) { @@ -33,7 +34,9 @@ export const textBasedLanguagedEditorStyles = ( zIndex: isCompactFocused ? 4 : 0, height: `${editorHeight}px`, border: isCompactFocused ? euiTheme.border.thin : 'none', - borderTopLeftRadius: isCodeEditorExpanded ? 0 : '6px', + borderLeft: editorIsInline || !isCompactFocused ? 'none' : euiTheme.border.thin, + borderRight: editorIsInline || !isCompactFocused ? 'none' : euiTheme.border.thin, + borderTopLeftRadius: isCodeEditorExpanded ? 0 : euiTheme.border.radius.medium, borderBottom: isCodeEditorExpanded ? 'none' : isCompactFocused @@ -45,8 +48,8 @@ export const textBasedLanguagedEditorStyles = ( width: isCodeEditorExpanded ? '100%' : `calc(100% - ${hasReference ? 80 : 40}px)`, alignItems: isCompactFocused ? 'flex-start' : 'center', border: !isCompactFocused ? euiTheme.border.thin : 'none', - borderTopLeftRadius: '6px', - borderBottomLeftRadius: '6px', + borderTopLeftRadius: euiTheme.border.radius.medium, + borderBottomLeftRadius: euiTheme.border.radius.medium, borderBottomWidth: hasErrors ? '2px' : '1px', borderBottomColor: hasErrors ? euiTheme.colors.danger : euiTheme.colors.lightShade, }, @@ -66,6 +69,8 @@ export const textBasedLanguagedEditorStyles = ( }, bottomContainer: { border: euiTheme.border.thin, + borderLeft: editorIsInline ? 'none' : euiTheme.border.thin, + borderRight: editorIsInline ? 'none' : euiTheme.border.thin, borderTop: isCodeEditorExpanded && !isCodeEditorExpandedFocused ? hasErrors @@ -75,29 +80,29 @@ export const textBasedLanguagedEditorStyles = ( backgroundColor: euiTheme.colors.lightestShade, paddingLeft: euiTheme.size.base, paddingRight: euiTheme.size.base, - paddingTop: euiTheme.size.xs, - paddingBottom: euiTheme.size.xs, + paddingTop: editorIsInline ? euiTheme.size.s : euiTheme.size.xs, + paddingBottom: editorIsInline ? euiTheme.size.s : euiTheme.size.xs, width: 'calc(100% + 2px)', position: 'relative' as 'relative', // cast string to type 'relative', marginTop: 0, marginLeft: 0, marginBottom: 0, - borderBottomLeftRadius: '6px', - borderBottomRightRadius: '6px', + borderBottomLeftRadius: editorIsInline ? 0 : euiTheme.border.radius.medium, + borderBottomRightRadius: editorIsInline ? 0 : euiTheme.border.radius.medium, }, topContainer: { - border: euiTheme.border.thin, - borderTopLeftRadius: '6px', - borderTopRightRadius: '6px', + border: editorIsInline ? 'none' : euiTheme.border.thin, + borderTopLeftRadius: editorIsInline ? 0 : euiTheme.border.radius.medium, + borderTopRightRadius: editorIsInline ? 0 : euiTheme.border.radius.medium, backgroundColor: euiTheme.colors.lightestShade, paddingLeft: euiTheme.size.base, paddingRight: euiTheme.size.base, - paddingTop: euiTheme.size.xs, - paddingBottom: euiTheme.size.xs, + paddingTop: editorIsInline ? euiTheme.size.s : euiTheme.size.xs, + paddingBottom: editorIsInline ? euiTheme.size.s : euiTheme.size.xs, width: 'calc(100% + 2px)', position: 'relative' as 'relative', // cast string to type 'relative', marginLeft: 0, - marginTop: euiTheme.size.s, + marginTop: editorIsInline ? 0 : euiTheme.size.s, }, dragResizeContainer: { width: '100%', diff --git a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx index 0be4c38eed74..173c023f8b61 100644 --- a/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx +++ b/packages/kbn-text-based-editor/src/text_based_languages_editor.test.tsx @@ -84,7 +84,7 @@ describe('TextBasedLanguagesEditor', () => { }); }); - it('should render the date info with no @timestamp detected', async () => { + it('should render the date info with no @timestamp found', async () => { const newProps = { ...props, isCodeEditorExpanded: true, @@ -93,11 +93,11 @@ describe('TextBasedLanguagesEditor', () => { const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); expect( component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text() - ).toStrictEqual('@timestamp not detected'); + ).toStrictEqual('@timestamp not found'); }); }); - it('should render the date info with @timestamp detected if detectTimestamp is true', async () => { + it('should render the date info with @timestamp found if detectTimestamp is true', async () => { const newProps = { ...props, isCodeEditorExpanded: true, @@ -107,7 +107,7 @@ describe('TextBasedLanguagesEditor', () => { const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); expect( component.find('[data-test-subj="TextBasedLangEditor-date-info"]').at(0).text() - ).toStrictEqual('@timestamp detected'); + ).toStrictEqual('@timestamp found'); }); }); @@ -265,4 +265,24 @@ describe('TextBasedLanguagesEditor', () => { expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0); }); }); + + it('should render correctly if editorIsInline prop is set to true', async () => { + const onTextLangQuerySubmit = jest.fn(); + const newProps = { + ...props, + isCodeEditorExpanded: true, + hideRunQueryText: true, + editorIsInline: true, + onTextLangQuerySubmit, + }; + await act(async () => { + const component = mount(renderTextBasedLanguagesEditorComponent({ ...newProps })); + expect(component.find('[data-test-subj="TextBasedLangEditor-run-query"]').length).toBe(0); + expect( + component.find('[data-test-subj="TextBasedLangEditor-run-query-button"]').length + ).not.toBe(1); + findTestSubject(component, 'TextBasedLangEditor-run-query-button').simulate('click'); + expect(onTextLangQuerySubmit).toHaveBeenCalled(); + }); + }); }); 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 312d08cadf0c..a6cdea64704d 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 @@ -65,19 +65,43 @@ import { fetchFieldsFromESQL } from './fetch_fields_from_esql'; import './overwrite.scss'; export interface TextBasedLanguagesEditorProps { + /** The aggregate type query */ query: AggregateQuery; + /** Callback running everytime the query changes */ onTextLangQueryChange: (query: AggregateQuery) => void; - onTextLangQuerySubmit: () => void; + /** Callback running when the user submits the query */ + onTextLangQuerySubmit: (query?: AggregateQuery) => void; + /** Can be used to expand/minimize the editor */ expandCodeEditor: (status: boolean) => void; + /** If it is true, the editor initializes with height EDITOR_INITIAL_HEIGHT_EXPANDED */ isCodeEditorExpanded: boolean; + /** If it is true, the editor displays the message @timestamp found + * The text based queries are relying on adhoc dataviews which + * can have an @timestamp timefield or nothing + */ detectTimestamp?: boolean; + /** Array of errors */ errors?: Error[]; + /** Warning string as it comes from ES */ warning?: string; + /** Disables the editor */ isDisabled?: boolean; + /** Indicator if the editor is on dark mode */ isDarkMode?: boolean; dataTestSubj?: string; + /** If true it hides the minimize button and the user can't return to the minimized version + * Useful when the application doesn't want to give this capability + */ hideMinimizeButton?: boolean; + /** Hide the Run query information which appears on the footer*/ hideRunQueryText?: boolean; + /** This is used for applications (such as the inline editing flyout in dashboards) + * which want to add the editor without being part of the Unified search component + * It renders a submit query button inside the editor + */ + editorIsInline?: boolean; + /** Disables the submit query action*/ + disableSubmitAction?: boolean; } interface TextBasedEditorDeps { @@ -94,6 +118,9 @@ const EDITOR_ONE_LINER_UNUSED_SPACE_WITH_ERRORS = 220; const KEYCODE_ARROW_UP = 38; const KEYCODE_ARROW_DOWN = 40; +// for editor width smaller than this value we want to start hiding some text +const BREAKPOINT_WIDTH = 410; + const languageId = (language: string) => { switch (language) { case 'esql': { @@ -125,6 +152,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ isDarkMode, hideMinimizeButton, hideRunQueryText, + editorIsInline, + disableSubmitAction, dataTestSubj, }: TextBasedLanguagesEditorProps) { const { euiTheme } = useEuiTheme(); @@ -137,6 +166,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ const [editorHeight, setEditorHeight] = useState( isCodeEditorExpanded ? EDITOR_INITIAL_HEIGHT_EXPANDED : EDITOR_INITIAL_HEIGHT ); + const [isSpaceReduced, setIsSpaceReduced] = useState(false); const [showLineNumbers, setShowLineNumbers] = useState(isCodeEditorExpanded); const [isCompactFocused, setIsCompactFocused] = useState(isCodeEditorExpanded); const [isCodeEditorExpandedFocused, setIsCodeEditorExpandedFocused] = useState(false); @@ -166,7 +196,8 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ Boolean(errors?.length), Boolean(warning), isCodeEditorExpandedFocused, - Boolean(documentationSections) + Boolean(documentationSections), + Boolean(editorIsInline) ); const isDark = isDarkMode; const editorModel = useRef(); @@ -216,6 +247,11 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ [editorHeight] ); + const onQuerySubmit = useCallback(() => { + const currentValue = editor1.current?.getValue(); + onTextLangQuerySubmit({ [language]: currentValue } as AggregateQuery); + }, [language, onTextLangQuerySubmit]); + const restoreInitialMode = () => { setIsCodeEditorExpandedFocused(false); if (isCodeEditorExpanded) return; @@ -355,6 +391,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ }, [code, isCodeEditorExpanded, isWordWrapped]); const onResize = ({ width }: { width: number }) => { + setIsSpaceReduced(Boolean(editorIsInline && width < BREAKPOINT_WIDTH)); calculateVisibleCode(width); if (editor1.current) { editor1.current.layout({ width, height: editorHeight }); @@ -514,6 +551,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ { expandCodeEditor(false); updateLinesFromModel = false; @@ -584,6 +623,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ sections={documentationSections} buttonProps={{ color: 'text', + size: 's', 'data-test-subj': 'TextBasedLangEditor-documentation', 'aria-label': i18n.translate( 'textBasedEditor.query.textBasedLanguagesEditor.documentationLabel', @@ -712,7 +752,7 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ // eslint-disable-next-line no-bitwise monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, function () { - onTextLangQuerySubmit(); + onQuerySubmit(); } ); if (!isCodeEditorExpanded) { @@ -729,9 +769,12 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} warning={editorWarning} onErrorClick={onErrorClick} - refreshErrors={onTextLangQuerySubmit} + runQuery={onQuerySubmit} detectTimestamp={detectTimestamp} + editorIsInline={editorIsInline} + disableSubmitAction={disableSubmitAction} hideRunQueryText={hideRunQueryText} + isSpaceReduced={isSpaceReduced} /> )}

    @@ -816,15 +859,19 @@ export const TextBasedLanguagesEditor = memo(function TextBasedLanguagesEditor({ errors={editorErrors} warning={editorWarning} onErrorClick={onErrorClick} - refreshErrors={onTextLangQuerySubmit} + runQuery={onQuerySubmit} detectTimestamp={detectTimestamp} hideRunQueryText={hideRunQueryText} + editorIsInline={editorIsInline} + disableSubmitAction={disableSubmitAction} + isSpaceReduced={isSpaceReduced} /> )} {isCodeEditorExpanded && ( )} diff --git a/packages/kbn-ui-actions-browser/index.ts b/packages/kbn-ui-actions-browser/index.ts index 9662013cf99e..076b77680826 100644 --- a/packages/kbn-ui-actions-browser/index.ts +++ b/packages/kbn-ui-actions-browser/index.ts @@ -15,7 +15,5 @@ export { visualizeGeoFieldTrigger, ROW_CLICK_TRIGGER, rowClickTrigger, - CATEGORIZE_FIELD_TRIGGER, - categorizeFieldTrigger, defaultTrigger, } from './src/triggers'; diff --git a/packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts b/packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts deleted file mode 100644 index a332a21acb43..000000000000 --- a/packages/kbn-ui-actions-browser/src/triggers/categorize_field_trigger.ts +++ /dev/null @@ -1,16 +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 { Trigger } from './trigger'; - -export const CATEGORIZE_FIELD_TRIGGER = 'CATEGORIZE_FIELD_TRIGGER'; -export const categorizeFieldTrigger: Trigger = { - id: CATEGORIZE_FIELD_TRIGGER, - title: 'Run pattern analysis', - description: 'Triggered when user wants to run pattern analysis on a field.', -}; diff --git a/packages/kbn-ui-actions-browser/src/triggers/index.ts b/packages/kbn-ui-actions-browser/src/triggers/index.ts index 433a9cd6dff4..091305791d85 100644 --- a/packages/kbn-ui-actions-browser/src/triggers/index.ts +++ b/packages/kbn-ui-actions-browser/src/triggers/index.ts @@ -11,4 +11,3 @@ export * from './row_click_trigger'; export * from './default_trigger'; export * from './visualize_field_trigger'; export * from './visualize_geo_field_trigger'; -export * from './categorize_field_trigger'; diff --git a/packages/kbn-unified-field-list/src/components/field_categorize_button/categorize_trigger_utils.ts b/packages/kbn-unified-field-list/src/components/field_categorize_button/categorize_trigger_utils.ts index afeb34e6572a..007a88b2c7f9 100644 --- a/packages/kbn-unified-field-list/src/components/field_categorize_button/categorize_trigger_utils.ts +++ b/packages/kbn-unified-field-list/src/components/field_categorize_button/categorize_trigger_utils.ts @@ -6,8 +6,8 @@ * Side Public License, v 1. */ -import type { UiActionsStart, CategorizeFieldContext } from '@kbn/ui-actions-plugin/public'; -import { CATEGORIZE_FIELD_TRIGGER } from '@kbn/ui-actions-browser/src/triggers'; +import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; +import { CATEGORIZE_FIELD_TRIGGER, type CategorizeFieldContext } from '@kbn/ml-ui-actions'; import type { DataViewField, DataView } from '@kbn/data-views-plugin/public'; async function getCompatibleActions( diff --git a/packages/kbn-unified-field-list/src/components/field_categorize_button/field_categorize_button.test.tsx b/packages/kbn-unified-field-list/src/components/field_categorize_button/field_categorize_button.test.tsx index 4e0d00b4549c..45569b344337 100644 --- a/packages/kbn-unified-field-list/src/components/field_categorize_button/field_categorize_button.test.tsx +++ b/packages/kbn-unified-field-list/src/components/field_categorize_button/field_categorize_button.test.tsx @@ -14,9 +14,12 @@ import { stubLogstashDataView as dataView } from '@kbn/data-views-plugin/common/ import { ActionInternal } from '@kbn/ui-actions-plugin/public'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; import { getFieldCategorizeButton } from './field_categorize_button'; -import { ACTION_CATEGORIZE_FIELD, CategorizeFieldContext } from '@kbn/ui-actions-plugin/public'; +import { + CATEGORIZE_FIELD_TRIGGER, + ACTION_CATEGORIZE_FIELD, + type CategorizeFieldContext, +} from '@kbn/ml-ui-actions'; import { TriggerContract } from '@kbn/ui-actions-plugin/public/triggers'; -import { CATEGORIZE_FIELD_TRIGGER } from '@kbn/ui-actions-browser'; const ORIGINATING_APP = 'test'; const mockExecuteAction = jest.fn(); diff --git a/packages/kbn-unified-field-list/tsconfig.json b/packages/kbn-unified-field-list/tsconfig.json index 27cbb23cf3d7..eeca808e1bee 100644 --- a/packages/kbn-unified-field-list/tsconfig.json +++ b/packages/kbn-unified-field-list/tsconfig.json @@ -31,6 +31,7 @@ "@kbn/ebt-tools", "@kbn/shared-ux-button-toolbar", "@kbn/field-utils", + "@kbn/ml-ui-actions", ], "exclude": ["target/**/*"] } diff --git a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.component.tsx b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.component.tsx index 96e80af24651..3705b5885f1a 100644 --- a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.component.tsx +++ b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.component.tsx @@ -29,6 +29,7 @@ export const RedirectAppLinks: FC = ({ children, navigateToUrl, currentAppId, + ...containerProps }) => { const containerRef = useRef(null); @@ -50,6 +51,7 @@ export const RedirectAppLinks: FC = ({ ref={containerRef} css={redirectAppLinksStyles} data-test-subj="kbnRedirectAppLink" + {...containerProps} > {children} diff --git a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx index 9a069881b212..da227ab023cb 100644 --- a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx +++ b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.container.tsx @@ -7,6 +7,7 @@ */ import React, { FC } from 'react'; +import type { RedirectAppLinksComponentProps } from '@kbn/shared-ux-link-redirect-app-types'; import { useServices } from './services'; import { RedirectAppLinks as Component } from './redirect_app_links.component'; @@ -22,6 +23,11 @@ import { RedirectAppLinks as Component } from './redirect_app_links.component'; * * ``` */ -export const RedirectAppLinks: FC<{}> = ({ children }) => ( - {children} +export const RedirectAppLinks: FC> = ({ + children, + ...props +}) => ( + + {children} + ); diff --git a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.tsx b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.tsx index 2909dcdbda17..89d8a61531e9 100644 --- a/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.tsx +++ b/packages/shared-ux/link/redirect_app/impl/src/redirect_app_links.tsx @@ -25,10 +25,11 @@ const isKibanaContract = (services: any): services is RedirectAppLinksKibanaDepe * with which consumers can wrap their components or solutions. */ export const RedirectAppLinks: FC = ({ children, ...props }) => { - const container = {children}; - if (isKibanaContract(props)) { - const { coreStart } = props; + const { coreStart, ...containerProps } = props; + const container = ( + {children} + ); return ( {container} @@ -36,7 +37,10 @@ export const RedirectAppLinks: FC = ({ children, ...props ); } - const { navigateToUrl, currentAppId } = props; + const { navigateToUrl, currentAppId, ...containerProps } = props; + const container = ( + {children} + ); return ( {container} diff --git a/packages/shared-ux/link/redirect_app/types/index.d.ts b/packages/shared-ux/link/redirect_app/types/index.d.ts index 186e86af8943..01899edea65d 100644 --- a/packages/shared-ux/link/redirect_app/types/index.d.ts +++ b/packages/shared-ux/link/redirect_app/types/index.d.ts @@ -32,7 +32,11 @@ export interface RedirectAppLinksKibanaDependencies { } /** Props for the `RedirectAppLinks` component. */ -export type RedirectAppLinksProps = RedirectAppLinksServices | RedirectAppLinksKibanaDependencies; +export type RedirectAppLinksProps = ( + | RedirectAppLinksServices + | RedirectAppLinksKibanaDependencies +) & + DetailedHTMLProps, HTMLDivElement>; /** Props for the `RedirectAppLinksComponent`. */ export interface RedirectAppLinksComponentProps diff --git a/renovate.json b/renovate.json index e4c1e0672c78..63ca5d0ba8a9 100644 --- a/renovate.json +++ b/renovate.json @@ -462,7 +462,8 @@ "Team:Operations", "release_note:skip" ], - "enabled": true + "enabled": true, + "allowedVersions": "<7.0" }, { "groupName": "react-query", @@ -647,4 +648,4 @@ "enabled": true } ] -} +} \ No newline at end of file diff --git a/scripts/es.js b/scripts/es.js index 1fcd221c9790..1cee27b7685b 100644 --- a/scripts/es.js +++ b/scripts/es.js @@ -20,6 +20,7 @@ kbnEs 'source-path': resolve(__dirname, '../../elasticsearch'), 'base-path': resolve(__dirname, '../.es'), ssl: false, + kibanaUrl: 'https://localhost:5601/', }) .catch(function (e) { console.error(e); diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index 911eecd45a9f..75a18378f56b 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -109,6 +109,38 @@ export function applyConfigOverrides(rawConfig, opts, extraCliOptions) { if (opts.dev) { if (opts.serverless) { setServerlessKibanaDevServiceAccountIfPossible(get, set, opts); + + // Load mock identity provider plugin and configure realm if supported (ES only supports SAML when run with SSL) + if (opts.ssl && canRequire('@kbn/mock-idp-plugin/common')) { + // Ensure the plugin is loaded in dynamically to exclude from production build + const { + MOCK_IDP_PLUGIN_PATH, + MOCK_IDP_REALM_NAME, + } = require('@kbn/mock-idp-plugin/common'); + + if (has('server.basePath')) { + console.log( + `Custom base path is not supported when running in Serverless, it will be removed.` + ); + _.unset(rawConfig, 'server.basePath'); + } + + set('plugins.paths', _.compact([].concat(get('plugins.paths'), MOCK_IDP_PLUGIN_PATH))); + set(`xpack.security.authc.providers.saml.${MOCK_IDP_REALM_NAME}`, { + order: Number.MAX_SAFE_INTEGER, + realm: MOCK_IDP_REALM_NAME, + icon: 'user', + description: 'Continue as Test User', + hint: 'Allows testing serverless user roles', + }); + // Add basic realm since defaults won't be applied when a provider has been configured + if (!has('xpack.security.authc.providers.basic')) { + set('xpack.security.authc.providers.basic.basic', { + order: 0, + enabled: true, + }); + } + } } if (!has('elasticsearch.serviceAccountToken') && opts.devCredentials !== false) { @@ -274,7 +306,9 @@ export default function (program) { // We can tell users they only have to run with `yarn start --run-examples` to get those // local links to work. Similar to what we do for "View in Console" links in our // elastic.co links. - basePath: opts.runExamples ? false : !!opts.basePath, + // We also want to run without base path when running in serverless mode so that Elasticsearch can + // connect to Kibana's mock identity provider. + basePath: opts.runExamples || isServerlessMode ? false : !!opts.basePath, optimize: !!opts.optimize, disableOptimizer: !opts.optimizer, oss: !!opts.oss, diff --git a/src/cli/tsconfig.json b/src/cli/tsconfig.json index ebbbc19f75c7..3b3c0854975d 100644 --- a/src/cli/tsconfig.json +++ b/src/cli/tsconfig.json @@ -17,6 +17,7 @@ "@kbn/config", "@kbn/dev-utils", "@kbn/apm-config-loader", + "@kbn/mock-idp-plugin", ], "exclude": [ "target/**/*", diff --git a/src/core/server/integration_tests/elasticsearch/error_logging.test.ts b/src/core/server/integration_tests/elasticsearch/error_logging.test.ts index 8cd4f5ae4113..f8deaa41ee86 100644 --- a/src/core/server/integration_tests/elasticsearch/error_logging.test.ts +++ b/src/core/server/integration_tests/elasticsearch/error_logging.test.ts @@ -86,6 +86,7 @@ describe('Error logging', () => { name: 'ResponseError', process: { pid: expect.any(Number), + uptime: expect.any(Number), }, }); } diff --git a/src/core/server/integration_tests/http/http_server.test.ts b/src/core/server/integration_tests/http/http_server.test.ts index da10b231b7a2..b901f7f85cb6 100644 --- a/src/core/server/integration_tests/http/http_server.test.ts +++ b/src/core/server/integration_tests/http/http_server.test.ts @@ -52,7 +52,7 @@ describe('Http server', () => { beforeEach(async () => { shutdownTimeout = config.shutdownTimeout.asMilliseconds(); - const { registerRouter, server: innerServer } = await server.setup(config); + const { registerRouter, server: innerServer } = await server.setup({ config$: of(config) }); innerServerListener = innerServer.listener; const router = new Router('', logger, enhanceWithContext, { diff --git a/src/core/server/integration_tests/http/router.test.ts b/src/core/server/integration_tests/http/router.test.ts index 1e5b28413451..f66cab0a07f5 100644 --- a/src/core/server/integration_tests/http/router.test.ts +++ b/src/core/server/integration_tests/http/router.test.ts @@ -408,7 +408,7 @@ describe('Options', () => { }); describe('idleSocket', () => { - it.skip('should timeout if payload sending has too long of an idle period', async () => { + it('should timeout if payload sending has too long of an idle period', async () => { const { server: innerServer, createRouter } = await server.setup(setupDeps); const router = createRouter('/'); @@ -420,7 +420,7 @@ describe('Options', () => { body: { accepts: ['application/json'], }, - timeout: { idleSocket: 10 }, + timeout: { idleSocket: 5 }, }, }, async (context, req, res) => { diff --git a/src/core/server/integration_tests/http/set_tls_config.test.ts b/src/core/server/integration_tests/http/set_tls_config.test.ts new file mode 100644 index 000000000000..6c198d820670 --- /dev/null +++ b/src/core/server/integration_tests/http/set_tls_config.test.ts @@ -0,0 +1,107 @@ +/* + * 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 supertest from 'supertest'; +import { KBN_CERT_PATH, KBN_KEY_PATH, ES_KEY_PATH, ES_CERT_PATH } from '@kbn/dev-utils'; +import { + createServer, + getListenerOptions, + getServerOptions, + setTlsConfig, +} from '@kbn/server-http-tools'; +import { + HttpConfig, + config as httpConfig, + cspConfig, + externalUrlConfig, +} from '@kbn/core-http-server-internal'; +import { flattenCertificateChain, fetchPeerCertificate, isServerTLS } from './tls_utils'; + +describe('setTlsConfig', () => { + const CSP_CONFIG = cspConfig.schema.validate({}); + const EXTERNAL_URL_CONFIG = externalUrlConfig.schema.validate({}); + + beforeAll(() => { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + }); + + it('replaces the TLS configuration on the HAPI server', async () => { + const rawHttpConfig = httpConfig.schema.validate({ + name: 'kibana', + host: '127.0.0.1', + port: 10002, + ssl: { + enabled: true, + certificate: KBN_CERT_PATH, + key: KBN_KEY_PATH, + cipherSuites: ['TLS_AES_256_GCM_SHA384'], + redirectHttpFromPort: 10003, + }, + shutdownTimeout: '1s', + }); + const firstConfig = new HttpConfig(rawHttpConfig, CSP_CONFIG, EXTERNAL_URL_CONFIG); + + const serverOptions = getServerOptions(firstConfig); + const listenerOptions = getListenerOptions(firstConfig); + const server = createServer(serverOptions, listenerOptions); + + server.route({ + method: 'GET', + path: '/', + handler: (request, toolkit) => { + return toolkit.response('ok'); + }, + }); + + await server.start(); + + const listener = server.listener; + + // force TS to understand what we're working with. + if (!isServerTLS(listener)) { + throw new Error('Server should be a TLS server'); + } + + const certificate = await fetchPeerCertificate(firstConfig.host, firstConfig.port); + const certificateChain = flattenCertificateChain(certificate); + + expect(isServerTLS(listener)).toEqual(true); + expect(certificateChain.length).toEqual(1); + expect(certificateChain[0].subject.CN).toEqual('kibana'); + + await supertest(listener).get('/').expect(200); + + const secondRawConfig = httpConfig.schema.validate({ + name: 'kibana', + host: '127.0.0.1', + port: 10002, + ssl: { + enabled: true, + certificate: ES_CERT_PATH, + key: ES_KEY_PATH, + cipherSuites: ['TLS_AES_256_GCM_SHA384'], + redirectHttpFromPort: 10003, + }, + shutdownTimeout: '1s', + }); + + const secondConfig = new HttpConfig(secondRawConfig, CSP_CONFIG, EXTERNAL_URL_CONFIG); + + setTlsConfig(server, secondConfig.ssl); + + const secondCertificate = await fetchPeerCertificate(firstConfig.host, firstConfig.port); + const secondCertificateChain = flattenCertificateChain(secondCertificate); + + expect(secondCertificateChain.length).toEqual(1); + expect(secondCertificateChain[0].subject.CN).toEqual('elasticsearch'); + + await supertest(listener).get('/').expect(200); + + await server.stop(); + }); +}); diff --git a/src/core/server/integration_tests/http/tls_config_reload.test.ts b/src/core/server/integration_tests/http/tls_config_reload.test.ts new file mode 100644 index 000000000000..b0c8f6abf5e5 --- /dev/null +++ b/src/core/server/integration_tests/http/tls_config_reload.test.ts @@ -0,0 +1,122 @@ +/* + * 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 supertest from 'supertest'; +import { duration } from 'moment'; +import { BehaviorSubject, of } from 'rxjs'; +import { KBN_CERT_PATH, KBN_KEY_PATH, ES_KEY_PATH, ES_CERT_PATH } from '@kbn/dev-utils'; +import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; +import { Router } from '@kbn/core-http-router-server-internal'; +import { + HttpServer, + HttpConfig, + config as httpConfig, + cspConfig, + externalUrlConfig, +} from '@kbn/core-http-server-internal'; +import { isServerTLS, flattenCertificateChain, fetchPeerCertificate } from './tls_utils'; + +const CSP_CONFIG = cspConfig.schema.validate({}); +const EXTERNAL_URL_CONFIG = externalUrlConfig.schema.validate({}); +const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {}); + +describe('HttpServer - TLS config', () => { + let server: HttpServer; + let logger: ReturnType; + + beforeAll(() => { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + }); + + beforeEach(() => { + const loggingService = loggingSystemMock.create(); + logger = loggingSystemMock.createLogger(); + server = new HttpServer(loggingService, 'tests', of(duration('1s'))); + }); + + it('supports dynamic reloading of the TLS configuration', async () => { + const rawHttpConfig = httpConfig.schema.validate({ + name: 'kibana', + host: '127.0.0.1', + port: 10002, + ssl: { + enabled: true, + certificate: KBN_CERT_PATH, + key: KBN_KEY_PATH, + cipherSuites: ['TLS_AES_256_GCM_SHA384'], + redirectHttpFromPort: 10003, + }, + shutdownTimeout: '1s', + }); + const firstConfig = new HttpConfig(rawHttpConfig, CSP_CONFIG, EXTERNAL_URL_CONFIG); + + const config$ = new BehaviorSubject(firstConfig); + + const { server: innerServer, registerRouter } = await server.setup({ config$ }); + const listener = innerServer.listener; + + const router = new Router('', logger, enhanceWithContext, { + isDev: false, + versionedRouteResolution: 'oldest', + }); + router.get( + { + path: '/', + validate: false, + }, + async (ctx, req, res) => { + return res.ok({ + body: 'ok', + }); + } + ); + registerRouter(router); + + await server.start(); + + // force TS to understand what we're working with. + if (!isServerTLS(listener)) { + throw new Error('Server should be a TLS server'); + } + + const certificate = await fetchPeerCertificate(firstConfig.host, firstConfig.port); + const certificateChain = flattenCertificateChain(certificate); + + expect(certificateChain.length).toEqual(1); + expect(certificateChain[0].subject.CN).toEqual('kibana'); + + await supertest(listener).get('/').expect(200); + + const secondRawConfig = httpConfig.schema.validate({ + name: 'kibana', + host: '127.0.0.1', + port: 10002, + ssl: { + enabled: true, + certificate: ES_CERT_PATH, + key: ES_KEY_PATH, + cipherSuites: ['TLS_AES_256_GCM_SHA384'], + redirectHttpFromPort: 10003, + }, + shutdownTimeout: '1s', + }); + + const secondConfig = new HttpConfig(secondRawConfig, CSP_CONFIG, EXTERNAL_URL_CONFIG); + config$.next(secondConfig); + + const secondCertificate = await fetchPeerCertificate(firstConfig.host, firstConfig.port); + const secondCertificateChain = flattenCertificateChain(secondCertificate); + + expect(secondCertificateChain.length).toEqual(1); + expect(secondCertificateChain[0].subject.CN).toEqual('elasticsearch'); + + await supertest(listener).get('/').expect(200); + + await server.stop(); + }); +}); diff --git a/src/core/server/integration_tests/http/tls_utils.ts b/src/core/server/integration_tests/http/tls_utils.ts new file mode 100644 index 000000000000..e565a61ae5dc --- /dev/null +++ b/src/core/server/integration_tests/http/tls_utils.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 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 { Server as NodeHttpServer } from 'http'; +import { Server as NodeTlsServer } from 'https'; +import tls from 'tls'; + +export function isServerTLS(server: NodeHttpServer): server is NodeTlsServer { + return 'setSecureContext' in server; +} + +export const fetchPeerCertificate = (host: string, port: number) => { + return new Promise((resolve, reject) => { + const socket = tls.connect({ host, port: Number(port), rejectUnauthorized: false }); + socket.once('secureConnect', () => { + const cert = socket.getPeerCertificate(true); + socket.destroy(); + resolve(cert); + }); + socket.once('error', reject); + }); +}; + +export const flattenCertificateChain = ( + cert: tls.DetailedPeerCertificate, + accumulator: tls.DetailedPeerCertificate[] = [] +) => { + accumulator.push(cert); + if (cert.issuerCertificate && cert.fingerprint256 !== cert.issuerCertificate.fingerprint256) { + flattenCertificateChain(cert.issuerCertificate, accumulator); + } + return accumulator; +}; diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json index 88cac5132132..78219114a51d 100644 --- a/src/core/tsconfig.json +++ b/src/core/tsconfig.json @@ -155,6 +155,8 @@ "@kbn/core-test-helpers-model-versions", "@kbn/core-plugins-contracts-browser", "@kbn/core-plugins-contracts-server", + "@kbn/dev-utils", + "@kbn/server-http-tools", ], "exclude": [ "target/**/*", diff --git a/src/dev/storybook/aliases.ts b/src/dev/storybook/aliases.ts index 98470ccf1365..88d8c04b4233 100644 --- a/src/dev/storybook/aliases.ts +++ b/src/dev/storybook/aliases.ts @@ -15,7 +15,6 @@ export const storybookAliases = { canvas: 'x-pack/plugins/canvas/storybook', cases: 'packages/kbn-cases-components/.storybook', cell_actions: 'packages/kbn-cell-actions/.storybook', - ci_composite: '.ci/.storybook', cloud_chat: 'x-pack/plugins/cloud_integrations/cloud_chat/.storybook', coloring: 'packages/kbn-coloring/.storybook', language_documentation_popover: 'packages/kbn-language-documentation-popover/.storybook', diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx index 0190bbaefa00..6afdf1429663 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx @@ -54,12 +54,14 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean } trackUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`); } - if ('aliasPath' in visType) { - appId = visType.aliasApp; - path = visType.aliasPath; - } else { + if (!('alias' in visType)) { + // this visualization is not an alias appId = 'visualize'; path = `#/create?type=${encodeURIComponent(visType.name)}`; + } else if (visType.alias && 'path' in visType.alias) { + // this visualization **is** an alias, and it has an app to redirect to for creation + appId = visType.alias.app; + path = visType.alias.path; } } else { appId = 'visualize'; 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 d2b6470650ca..18f26704221a 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 @@ -104,10 +104,11 @@ export const EditorMenu = ({ createNewVisType, createNewEmbeddable, isDisabled } const promotedVisTypes = getSortedVisTypesByGroup(VisGroups.PROMOTED); const aggsBasedVisTypes = getSortedVisTypesByGroup(VisGroups.AGGBASED); const toolVisTypes = getSortedVisTypesByGroup(VisGroups.TOOLS); - const visTypeAliases = getVisTypeAliases().sort( - ({ promotion: a = false }: VisTypeAlias, { promotion: b = false }: VisTypeAlias) => + const visTypeAliases = getVisTypeAliases() + .sort(({ promotion: a = false }: VisTypeAlias, { promotion: b = false }: VisTypeAlias) => a === b ? 0 : a ? -1 : 1 - ); + ) + .filter(({ disableCreate }: VisTypeAlias) => !disableCreate); const factories = unwrappedEmbeddableFactories.filter( ({ isEditable, factory: { type, canCreateNew, isContainerType } }) => diff --git a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx index 8767b5abe356..de7d79d456b9 100644 --- a/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx +++ b/src/plugins/dashboard/public/dashboard_container/component/empty_screen/dashboard_empty_screen.tsx @@ -10,21 +10,21 @@ import React, { useCallback, useMemo } from 'react'; import useObservable from 'react-use/lib/useObservable'; import { - EuiText, - EuiImage, EuiButton, - EuiFlexItem, - EuiFlexGroup, EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiImage, EuiPageTemplate, + EuiText, } from '@elastic/eui'; import { METRIC_TYPE } from '@kbn/analytics'; import { ViewMode } from '@kbn/embeddable-plugin/public'; +import { DASHBOARD_UI_METRIC_ID } from '../../../dashboard_constants'; import { pluginServices } from '../../../services/plugin_services'; -import { emptyScreenStrings } from '../../_dashboard_container_strings'; import { useDashboardContainer } from '../../embeddable/dashboard_container'; -import { DASHBOARD_UI_METRIC_ID } from '../../../dashboard_constants'; +import { emptyScreenStrings } from '../../_dashboard_container_strings'; export function DashboardEmptyScreen() { const { @@ -53,7 +53,7 @@ export function DashboardEmptyScreen() { const originatingApp = embeddableAppContext?.currentAppId; const goToLens = useCallback(() => { - if (!lensAlias || !lensAlias.aliasPath) return; + if (!lensAlias || !lensAlias.alias) return; const trackUiMetric = usageCollection.reportUiCounter?.bind( usageCollection, DASHBOARD_UI_METRIC_ID @@ -62,8 +62,8 @@ export function DashboardEmptyScreen() { if (trackUiMetric) { trackUiMetric(METRIC_TYPE.CLICK, `${lensAlias.name}:create`); } - getStateTransfer().navigateToEditor(lensAlias.aliasApp, { - path: lensAlias.aliasPath, + getStateTransfer().navigateToEditor(lensAlias.alias.app, { + path: lensAlias.alias.path, state: { originatingApp, originatingPath, diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index ec30a92bae99..ee434c4d05cf 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -67,10 +67,6 @@ function normalizeType(type: string): DatatableColumnType { } } -function sanitize(value: string) { - return value.replace(/[\(\)]/g, '_'); -} - function extractTypeAndReason(attributes: any): { type?: string; reason?: string } { if (['type', 'reason'].every((prop) => prop in attributes)) { return attributes; @@ -249,8 +245,8 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { map(({ rawResponse: body, warning }) => { const columns = body.columns?.map(({ name, type }) => ({ - id: sanitize(name), - name: sanitize(name), + id: name, + name, meta: { type: normalizeType(type) }, })) ?? []; const columnNames = columns.map(({ name }) => name); diff --git a/src/plugins/data_views/docs/openapi/bundled.json b/src/plugins/data_views/docs/openapi/bundled.json index d661e0a7cbaa..e4f7e9856e2b 100644 --- a/src/plugins/data_views/docs/openapi/bundled.json +++ b/src/plugins/data_views/docs/openapi/bundled.json @@ -740,7 +740,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "examples": { diff --git a/src/plugins/data_views/docs/openapi/bundled.yaml b/src/plugins/data_views/docs/openapi/bundled.yaml index c6e52614b66e..65ffd986ade7 100644 --- a/src/plugins/data_views/docs/openapi/bundled.yaml +++ b/src/plugins/data_views/docs/openapi/bundled.yaml @@ -474,7 +474,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' examples: get_data_views_response: summary: The get all data views API returns a list of data views. diff --git a/src/plugins/data_views/docs/openapi/entrypoint.yaml b/src/plugins/data_views/docs/openapi/entrypoint.yaml index 991d0e32154a..697fd554dae8 100644 --- a/src/plugins/data_views/docs/openapi/entrypoint.yaml +++ b/src/plugins/data_views/docs/openapi/entrypoint.yaml @@ -52,7 +52,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - apiKeyAuth: [] diff --git a/src/plugins/links/kibana.jsonc b/src/plugins/links/kibana.jsonc index 5f0796d55b43..a1e59cff9dc3 100644 --- a/src/plugins/links/kibana.jsonc +++ b/src/plugins/links/kibana.jsonc @@ -12,9 +12,10 @@ "dashboard", "embeddable", "kibanaReact", + "kibanaUtils", "presentationUtil", "uiActionsEnhanced", - "kibanaUtils" + "visualizations" ], "optionalPlugins": ["triggersActionsUi"], "requiredBundles": ["savedObjects"] diff --git a/src/plugins/links/public/components/dashboard_link/dashboard_link_component.tsx b/src/plugins/links/public/components/dashboard_link/dashboard_link_component.tsx index 5ff2bacaf49f..4ad4608080b5 100644 --- a/src/plugins/links/public/components/dashboard_link/dashboard_link_component.tsx +++ b/src/plugins/links/public/components/dashboard_link/dashboard_link_component.tsx @@ -7,24 +7,24 @@ */ import classNames from 'classnames'; -import useAsync from 'react-use/lib/useAsync'; import React, { useEffect, useMemo, useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; import useObservable from 'react-use/lib/useObservable'; -import { - DashboardDrilldownOptions, - DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS, -} from '@kbn/presentation-util-plugin/public'; import { EuiButtonEmpty, EuiListGroupItem } from '@elastic/eui'; -import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; import { DashboardLocatorParams, getDashboardLocatorParamsFromEmbeddable, } from '@kbn/dashboard-plugin/public'; +import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; +import { + DashboardDrilldownOptions, + DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS, +} from '@kbn/presentation-util-plugin/public'; -import { LINKS_VERTICAL_LAYOUT, LinksLayoutType, Link } from '../../../common/content_management'; +import { Link, LinksLayoutType, LINKS_VERTICAL_LAYOUT } from '../../../common/content_management'; +import { useLinks } from '../links_hooks'; import { DashboardLinkStrings } from './dashboard_link_strings'; -import { useLinks } from '../../embeddable/links_embeddable'; import { fetchDashboard } from './dashboard_link_tools'; export const DashboardLinkComponent = ({ diff --git a/src/plugins/links/public/components/editor/links_editor.tsx b/src/plugins/links/public/components/editor/links_editor.tsx index 0fb22efaf850..12e48e5aa463 100644 --- a/src/plugins/links/public/components/editor/links_editor.tsx +++ b/src/plugins/links/public/components/editor/links_editor.tsx @@ -7,41 +7,42 @@ */ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import useMountedState from 'react-use/lib/useMountedState'; import { - EuiForm, EuiBadge, - EuiTitle, EuiButton, - EuiSwitch, - EuiFormRow, - EuiToolTip, - EuiFlexItem, - EuiFlexGroup, - EuiDroppable, - EuiDraggable, - EuiFlyoutBody, EuiButtonEmpty, EuiButtonGroup, - EuiFlyoutFooter, - EuiFlyoutHeader, + EuiButtonGroupOptionProps, EuiDragDropContext, euiDragDropReorder, - EuiButtonGroupOptionProps, + EuiDraggable, + EuiDroppable, + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiForm, + EuiFormRow, + EuiSwitch, + EuiTitle, + EuiToolTip, } from '@elastic/eui'; import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; -import { LinksLayoutInfo } from '../../embeddable/types'; import { Link, LinksLayoutType, LINKS_HORIZONTAL_LAYOUT, LINKS_VERTICAL_LAYOUT, } from '../../../common/content_management'; +import { memoizedGetOrderedLinkList } from '../../editor/links_editor_tools'; +import { openLinkEditorFlyout } from '../../editor/open_link_editor_flyout'; +import { LinksLayoutInfo } from '../../embeddable/types'; import { coreServices } from '../../services/kibana_services'; import { LinksStrings } from '../links_strings'; -import { openLinkEditorFlyout } from '../../editor/open_link_editor_flyout'; -import { memoizedGetOrderedLinkList } from '../../editor/links_editor_tools'; import { LinksEditorEmptyPrompt } from './links_editor_empty_prompt'; import { LinksEditorSingleLink } from './links_editor_single_link'; @@ -80,6 +81,7 @@ const LinksEditor = ({ isByReference: boolean; }) => { const toasts = coreServices.notifications.toasts; + const isMounted = useMountedState(); const editLinkFlyoutRef = useRef(null); const [currentLayout, setCurrentLayout] = useState( @@ -294,7 +296,9 @@ const LinksEditor = ({ }); }) .finally(() => { - setIsSaving(false); + if (isMounted()) { + setIsSaving(false); + } }); } else { onAddToDashboard(orderedLinks, currentLayout); diff --git a/src/plugins/links/public/components/links_component.tsx b/src/plugins/links/public/components/links_component.tsx index c72c0db04fd5..0da40365abad 100644 --- a/src/plugins/links/public/components/links_component.tsx +++ b/src/plugins/links/public/components/links_component.tsx @@ -6,29 +6,28 @@ * Side Public License, v 1. */ +import { EuiListGroup, EuiPanel } from '@elastic/eui'; import React, { useEffect, useMemo } from 'react'; import useMap from 'react-use/lib/useMap'; -import { EuiListGroup, EuiPanel } from '@elastic/eui'; -import { useLinks } from '../embeddable/links_embeddable'; -import { ExternalLinkComponent } from './external_link/external_link_component'; -import { DashboardLinkComponent } from './dashboard_link/dashboard_link_component'; -import { memoizedGetOrderedLinkList } from '../editor/links_editor_tools'; import { DASHBOARD_LINK_TYPE, LINKS_HORIZONTAL_LAYOUT, LINKS_VERTICAL_LAYOUT, } from '../../common/content_management'; +import { memoizedGetOrderedLinkList } from '../editor/links_editor_tools'; +import { DashboardLinkComponent } from './dashboard_link/dashboard_link_component'; +import { ExternalLinkComponent } from './external_link/external_link_component'; import './links_component.scss'; +import { useLinks, useLinksAttributes } from './links_hooks'; export const LinksComponent = () => { const linksEmbeddable = useLinks(); - const links = linksEmbeddable.select((state) => state.componentState.links); - const layout = linksEmbeddable.select((state) => state.componentState.layout); + const linksAttributes = useLinksAttributes(); const [linksLoading, { set: setLinkIsLoading }] = useMap( Object.fromEntries( - (links ?? []).map((link) => { + (linksAttributes?.links ?? []).map((link) => { return [link.id, true]; }) ) @@ -43,12 +42,12 @@ export const LinksComponent = () => { }, [linksLoading, linksEmbeddable]); const orderedLinks = useMemo(() => { - if (!links) return []; - return memoizedGetOrderedLinkList(links); - }, [links]); + if (!linksAttributes?.links) return []; + return memoizedGetOrderedLinkList(linksAttributes?.links); + }, [linksAttributes]); const linkItems: { [id: string]: { id: string; content: JSX.Element } } = useMemo(() => { - return (links ?? []).reduce((prev, currentLink) => { + return (linksAttributes?.links ?? []).reduce((prev, currentLink) => { return { ...prev, [currentLink.id]: { @@ -58,7 +57,7 @@ export const LinksComponent = () => { setLinkIsLoading(currentLink.id, true)} onRender={() => setLinkIsLoading(currentLink.id, false)} /> @@ -66,26 +65,26 @@ export const LinksComponent = () => { setLinkIsLoading(currentLink.id, false)} /> ), }, }; }, {}); - }, [links, layout, setLinkIsLoading]); + }, [linksAttributes?.links, linksAttributes?.layout, setLinkIsLoading]); return ( {orderedLinks.map((link) => linkItems[link.id].content)} diff --git a/src/plugins/links/public/components/links_hooks.tsx b/src/plugins/links/public/components/links_hooks.tsx new file mode 100644 index 000000000000..aa33c9d0f3ac --- /dev/null +++ b/src/plugins/links/public/components/links_hooks.tsx @@ -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 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 { useContext, useEffect, useState } from 'react'; + +import { LinksAttributes } from '../../common/content_management'; +import { LinksContext, LinksEmbeddable } from '../embeddable/links_embeddable'; + +export const useLinks = (): LinksEmbeddable => { + const linksEmbeddable = useContext(LinksContext); + if (linksEmbeddable == null) { + throw new Error('useLinks must be used inside LinksContext.'); + } + return linksEmbeddable!; +}; + +export const useLinksAttributes = (): LinksAttributes | undefined => { + const linksEmbeddable = useLinks(); + const [attributes, setAttributes] = useState( + linksEmbeddable.attributes + ); + + useEffect(() => { + const attributesSubscription = linksEmbeddable.attributes$.subscribe((newAttributes) => { + setAttributes(newAttributes); + }); + return () => { + attributesSubscription.unsubscribe(); + }; + }, [linksEmbeddable.attributes$]); + + return attributes; +}; diff --git a/src/plugins/links/public/content_management/links_content_management_client.ts b/src/plugins/links/public/content_management/links_content_management_client.ts index 777fd8731d69..586b5aff5efb 100644 --- a/src/plugins/links/public/content_management/links_content_management_client.ts +++ b/src/plugins/links/public/content_management/links_content_management_client.ts @@ -7,8 +7,9 @@ */ import type { SearchQuery } from '@kbn/content-management-plugin/common'; +import { SerializableAttributes, VisualizationClient } from '@kbn/visualizations-plugin/public'; +import { CONTENT_ID as contentTypeId, CONTENT_ID } from '../../common'; import type { LinksCrudTypes } from '../../common/content_management'; -import { CONTENT_ID as contentTypeId } from '../../common'; import { contentManagement } from '../services/kibana_services'; const get = async (id: string) => { @@ -65,3 +66,9 @@ export const linksClient = { delete: deleteLinks, search, }; + +export function getLinksClient< + Attr extends SerializableAttributes = SerializableAttributes +>(): VisualizationClient { + return linksClient as unknown as VisualizationClient; +} diff --git a/src/plugins/links/public/editor/open_editor_flyout.tsx b/src/plugins/links/public/editor/open_editor_flyout.tsx index 1c722a484eb1..d47b178d5ff9 100644 --- a/src/plugins/links/public/editor/open_editor_flyout.tsx +++ b/src/plugins/links/public/editor/open_editor_flyout.tsx @@ -7,18 +7,20 @@ */ import React from 'react'; +import { skip, take } from 'rxjs/operators'; -import { withSuspense } from '@kbn/shared-ux-utility'; -import { toMountPoint } from '@kbn/react-kibana-mount'; import { EuiLoadingSpinner, EuiPanel } from '@elastic/eui'; -import { tracksOverlays } from '@kbn/embeddable-plugin/public'; import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; +import { tracksOverlays } from '@kbn/embeddable-plugin/public'; +import { toMountPoint } from '@kbn/react-kibana-mount'; +import { withSuspense } from '@kbn/shared-ux-utility'; -import { LinksInput, LinksByReferenceInput, LinksEditorFlyoutReturn } from '../embeddable/types'; -import { coreServices } from '../services/kibana_services'; -import { runSaveToLibrary } from '../content_management/save_to_library'; +import { OverlayRef } from '@kbn/core-mount-utils-browser'; import { Link, LinksLayoutType } from '../../common/content_management'; +import { runSaveToLibrary } from '../content_management/save_to_library'; +import { LinksByReferenceInput, LinksEditorFlyoutReturn, LinksInput } from '../embeddable/types'; import { getLinksAttributeService } from '../services/attribute_service'; +import { coreServices } from '../services/kibana_services'; const LazyLinksEditor = React.lazy(() => import('../components/editor/links_editor')); @@ -40,7 +42,8 @@ export async function openEditorFlyout( const { attributes } = await attributeService.unwrapAttributes(initialInput); const isByReference = attributeService.inputIsRefType(initialInput); const initialLinks = attributes?.links; - const overlayTracker = tracksOverlays(parentDashboard) ? parentDashboard : undefined; + const overlayTracker = + parentDashboard && tracksOverlays(parentDashboard) ? parentDashboard : undefined; if (!initialLinks) { /** @@ -55,6 +58,22 @@ export async function openEditorFlyout( } return new Promise((resolve, reject) => { + const closeEditorFlyout = (editorFlyout: OverlayRef) => { + if (overlayTracker) { + overlayTracker.clearOverlays(); + } else { + editorFlyout.close(); + } + }; + + /** + * Close the flyout whenever the app changes - this handles cases for when the flyout is open outside of the + * Dashboard app (`overlayTracker` is not available) + */ + coreServices.application.currentAppId$.pipe(skip(1), take(1)).subscribe(() => { + if (!overlayTracker) editorFlyout.close(); + }); + const onSaveToLibrary = async (newLinks: Link[], newLayout: LinksLayoutType) => { const newAttributes = { ...attributes, @@ -74,7 +93,7 @@ export async function openEditorFlyout( attributes: newAttributes, }); parentDashboard?.reload(); - if (overlayTracker) overlayTracker.clearOverlays(); + closeEditorFlyout(editorFlyout); }; const onAddToDashboard = (newLinks: Link[], newLayout: LinksLayoutType) => { @@ -94,12 +113,12 @@ export async function openEditorFlyout( attributes: newAttributes, }); parentDashboard?.reload(); - if (overlayTracker) overlayTracker.clearOverlays(); + closeEditorFlyout(editorFlyout); }; const onCancel = () => { reject(); - if (overlayTracker) overlayTracker.clearOverlays(); + closeEditorFlyout(editorFlyout); }; const editorFlyout = coreServices.overlays.openFlyout( @@ -125,6 +144,8 @@ export async function openEditorFlyout( } ); - if (overlayTracker) overlayTracker.openOverlay(editorFlyout); + if (overlayTracker) { + overlayTracker.openOverlay(editorFlyout); + } }); } diff --git a/src/plugins/links/public/embeddable/links_embeddable.tsx b/src/plugins/links/public/embeddable/links_embeddable.tsx index 032b0099ed45..d803b9df9e8c 100644 --- a/src/plugins/links/public/embeddable/links_embeddable.tsx +++ b/src/plugins/links/public/embeddable/links_embeddable.tsx @@ -6,37 +6,25 @@ * Side Public License, v 1. */ -import React, { createContext, useContext } from 'react'; -import { unmountComponentAtNode } from 'react-dom'; -import { Subscription, distinctUntilChanged, skip, switchMap } from 'rxjs'; import deepEqual from 'fast-deep-equal'; +import React, { createContext } from 'react'; +import { unmountComponentAtNode } from 'react-dom'; +import { distinctUntilChanged, skip, Subject, Subscription, switchMap } from 'rxjs'; +import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; import { AttributeService, Embeddable, ReferenceOrValueEmbeddable, SavedObjectEmbeddableInput, } from '@kbn/embeddable-plugin/public'; -import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; -import { ReduxEmbeddableTools, ReduxToolsPackage } from '@kbn/presentation-util-plugin/public'; -import { linksReducers } from './links_reducers'; -import { LinksByReferenceInput, LinksByValueInput, LinksReduxState } from './types'; -import { LinksComponent } from '../components/links_component'; -import { LinksInput, LinksOutput } from './types'; -import { LinksAttributes } from '../../common/content_management'; import { CONTENT_ID } from '../../common'; +import { LinksAttributes } from '../../common/content_management'; +import { LinksComponent } from '../components/links_component'; +import { LinksByReferenceInput, LinksByValueInput, LinksInput, LinksOutput } from './types'; export const LinksContext = createContext(null); -export const useLinks = (): LinksEmbeddable => { - const linksEmbeddable = useContext(LinksContext); - if (linksEmbeddable == null) { - throw new Error('useLinks must be used inside LinksContext.'); - } - return linksEmbeddable!; -}; - -type LinksReduxEmbeddableTools = ReduxEmbeddableTools; export interface LinksConfig { editable: boolean; @@ -53,20 +41,10 @@ export class LinksEmbeddable private isDestroyed?: boolean; private subscriptions: Subscription = new Subscription(); - // state management - /** - * TODO: Keep track of the necessary state without the redux embeddable tools; it's kind of overkill here. - * Related issue: https://github.com/elastic/kibana/issues/167577 - */ - public select: LinksReduxEmbeddableTools['select']; - public getState: LinksReduxEmbeddableTools['getState']; - public dispatch: LinksReduxEmbeddableTools['dispatch']; - public onStateChange: LinksReduxEmbeddableTools['onStateChange']; - - private cleanupStateTools: () => void; + public attributes?: LinksAttributes; + public attributes$ = new Subject(); constructor( - reduxToolsPackage: ReduxToolsPackage, config: LinksConfig, initialInput: LinksInput, private attributeService: AttributeService, @@ -81,29 +59,11 @@ export class LinksEmbeddable parent ); - /** Build redux embeddable tools */ - const reduxEmbeddableTools = reduxToolsPackage.createReduxEmbeddableTools< - LinksReduxState, - typeof linksReducers - >({ - embeddable: this, - reducers: linksReducers, - initialComponentState: { - title: '', - }, - }); - - this.select = reduxEmbeddableTools.select; - this.getState = reduxEmbeddableTools.getState; - this.dispatch = reduxEmbeddableTools.dispatch; - this.cleanupStateTools = reduxEmbeddableTools.cleanup; - this.onStateChange = reduxEmbeddableTools.onStateChange; - this.initializeSavedLinks() .then(() => this.setInitializationFinished()) .catch((e: Error) => this.onFatalError(e)); - // By-value panels should update the componentState when input changes + // By-value panels should update the links attributes when input changes this.subscriptions.add( this.getInput$() .pipe( @@ -113,25 +73,28 @@ export class LinksEmbeddable ) .subscribe() ); + + // Keep attributes in sync with subject value so it can be used in output + this.subscriptions.add( + this.attributes$.pipe(distinctUntilChanged(deepEqual)).subscribe((attributes) => { + this.attributes = attributes; + }) + ); } private async initializeSavedLinks() { const { attributes } = await this.attributeService.unwrapAttributes(this.getInput()); - if (this.isDestroyed) return; - - this.dispatch.setAttributes(attributes); - + this.attributes$.next(attributes); await this.initializeOutput(); } private async initializeOutput() { - const attributes = this.getState().componentState; const { title, description } = this.getInput(); this.updateOutput({ - defaultTitle: attributes.title, - defaultDescription: attributes.description, - title: title ?? attributes.title, - description: description ?? attributes.description, + defaultTitle: this.attributes?.title, + defaultDescription: this.attributes?.description, + title: title ?? this.attributes?.title, + description: description ?? this.attributes?.description, }); } @@ -162,7 +125,7 @@ export class LinksEmbeddable public async reload() { if (this.isDestroyed) return; - // By-reference embeddable panels are reloaded when changed, so update the componentState + // By-reference embeddable panels are reloaded when changed, so update the attributes this.initializeSavedLinks(); if (this.domNode) { this.render(this.domNode); @@ -173,7 +136,6 @@ export class LinksEmbeddable this.isDestroyed = true; super.destroy(); this.subscriptions.unsubscribe(); - this.cleanupStateTools(); if (this.domNode) { unmountComponentAtNode(this.domNode); } diff --git a/src/plugins/links/public/embeddable/links_embeddable_factory.ts b/src/plugins/links/public/embeddable/links_embeddable_factory.ts index e0502d34a742..e1446aff316a 100644 --- a/src/plugins/links/public/embeddable/links_embeddable_factory.ts +++ b/src/plugins/links/public/embeddable/links_embeddable_factory.ts @@ -6,34 +6,33 @@ * Side Public License, v 1. */ +import { DASHBOARD_GRID_COLUMN_COUNT } from '@kbn/dashboard-plugin/public'; +import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; +import { IProvidesPanelPlacementSettings } from '@kbn/dashboard-plugin/public/dashboard_container/component/panel_placement/types'; +import { EmbeddableStateWithType } from '@kbn/embeddable-plugin/common'; import { EmbeddableFactory, EmbeddableFactoryDefinition, ErrorEmbeddable, } from '@kbn/embeddable-plugin/public'; import { - MigrateFunctionsObject, GetMigrationFunctionObjectFn, + MigrateFunctionsObject, } from '@kbn/kibana-utils-plugin/common'; -import { EmbeddableStateWithType } from '@kbn/embeddable-plugin/common'; -import { DASHBOARD_GRID_COLUMN_COUNT } from '@kbn/dashboard-plugin/public'; import { UiActionsPresentableGrouping } from '@kbn/ui-actions-plugin/public'; -import { lazyLoadReduxToolsPackage } from '@kbn/presentation-util-plugin/public'; -import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; -import { IProvidesPanelPlacementSettings } from '@kbn/dashboard-plugin/public/dashboard_container/component/panel_placement/types'; +import { APP_ICON, APP_NAME, CONTENT_ID } from '../../common'; +import { LinksAttributes } from '../../common/content_management'; +import { extract, inject } from '../../common/embeddable'; +import { LinksStrings } from '../components/links_strings'; +import { getLinksAttributeService } from '../services/attribute_service'; import { coreServices, presentationUtil, untilPluginStartServicesReady, } from '../services/kibana_services'; -import { extract, inject } from '../../common/embeddable'; import type { LinksEmbeddable } from './links_embeddable'; -import { LinksStrings } from '../components/links_strings'; -import { APP_ICON, APP_NAME, CONTENT_ID } from '../../common'; -import { LinksAttributes } from '../../common/content_management'; -import { getLinksAttributeService } from '../services/attribute_service'; -import { LinksInput, LinksByReferenceInput, LinksEditorFlyoutReturn } from './types'; +import { LinksByReferenceInput, LinksEditorFlyoutReturn, LinksInput } from './types'; export type LinksFactory = EmbeddableFactory; @@ -111,12 +110,10 @@ export class LinksFactoryDefinition public async create(initialInput: LinksInput, parent: DashboardContainer) { await untilPluginStartServicesReady(); - const reduxEmbeddablePackage = await lazyLoadReduxToolsPackage(); const { LinksEmbeddable } = await import('./links_embeddable'); const editable = await this.isEditable(); return new LinksEmbeddable( - reduxEmbeddablePackage, { editable }, { ...getDefaultLinksInput(), ...initialInput }, getLinksAttributeService(), @@ -128,8 +125,6 @@ export class LinksFactoryDefinition initialInput: LinksInput, parent?: DashboardContainer ): Promise { - if (!parent) return { newInput: {} }; - const { openEditorFlyout } = await import('../editor/open_editor_flyout'); const { newInput, attributes } = await openEditorFlyout( diff --git a/src/plugins/links/public/embeddable/links_reducers.ts b/src/plugins/links/public/embeddable/links_reducers.ts deleted file mode 100644 index 659b19058adb..000000000000 --- a/src/plugins/links/public/embeddable/links_reducers.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 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 { WritableDraft } from 'immer/dist/types/types-external'; - -import { PayloadAction } from '@reduxjs/toolkit'; - -import { LinksReduxState } from './types'; -import { LinksAttributes } from '../../common/content_management'; - -export const linksReducers = { - setLoading: (state: WritableDraft, action: PayloadAction) => { - state.output.loading = action.payload; - }, - - setAttributes: ( - state: WritableDraft, - action: PayloadAction - ) => { - state.componentState = { ...action.payload }; - }, -}; diff --git a/src/plugins/links/public/plugin.ts b/src/plugins/links/public/plugin.ts index 7927de88b80e..6569f6d76780 100644 --- a/src/plugins/links/public/plugin.ts +++ b/src/plugins/links/public/plugin.ts @@ -6,22 +6,28 @@ * Side Public License, v 1. */ -import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { ContentManagementPublicSetup, ContentManagementPublicStart, } from '@kbn/content-management-plugin/public'; +import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public'; import { DashboardStart } from '@kbn/dashboard-plugin/public'; +import { DashboardContainer } from '@kbn/dashboard-plugin/public/dashboard_container'; import { EmbeddableSetup, EmbeddableStart } from '@kbn/embeddable-plugin/public'; import { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public'; +import { VisualizationsSetup } from '@kbn/visualizations-plugin/public'; -import { APP_NAME } from '../common'; +import { APP_ICON, APP_NAME, CONTENT_ID, LATEST_VERSION } from '../common'; +import { LinksCrudTypes } from '../common/content_management'; +import { LinksStrings } from './components/links_strings'; +import { getLinksClient } from './content_management/links_content_management_client'; import { LinksFactoryDefinition } from './embeddable'; -import { CONTENT_ID, LATEST_VERSION } from '../common'; +import { LinksByReferenceInput } from './embeddable/types'; import { setKibanaServices } from './services/kibana_services'; export interface LinksSetupDependencies { embeddable: EmbeddableSetup; + visualizations: VisualizationsSetup; contentManagement: ContentManagementPublicSetup; } @@ -39,7 +45,9 @@ export class LinksPlugin public setup(core: CoreSetup, plugins: LinksSetupDependencies) { core.getStartServices().then(([_, deps]) => { - plugins.embeddable.registerEmbeddableFactory(CONTENT_ID, new LinksFactoryDefinition()); + const linksFactory = new LinksFactoryDefinition(); + + plugins.embeddable.registerEmbeddableFactory(CONTENT_ID, linksFactory); plugins.contentManagement.registry.register({ id: CONTENT_ID, @@ -48,6 +56,53 @@ export class LinksPlugin }, name: APP_NAME, }); + + const getExplicitInput = async ({ + savedObjectId, + parent, + }: { + savedObjectId?: string; + parent?: DashboardContainer; + }) => { + try { + await linksFactory.getExplicitInput({ savedObjectId } as LinksByReferenceInput, parent); + } catch { + // swallow any errors - this just means that the user cancelled editing + } + return; + }; + + plugins.visualizations.registerAlias({ + disableCreate: true, // do not allow creation through visualization listing page + name: CONTENT_ID, + title: APP_NAME, + icon: APP_ICON, + description: LinksStrings.getDescription(), + stage: 'experimental', + appExtensions: { + visualizations: { + docTypes: [CONTENT_ID], + searchFields: ['title^3'], + client: getLinksClient, + toListItem(linkItem: LinksCrudTypes['Item']) { + const { id, type, updatedAt, attributes } = linkItem; + const { title, description } = attributes; + + return { + id, + title, + editor: { onEdit: (savedObjectId: string) => getExplicitInput({ savedObjectId }) }, + description, + updatedAt, + icon: APP_ICON, + typeTitle: APP_NAME, + stage: 'experimental', + savedObjectType: type, + }; + }, + }, + }, + }); }); } diff --git a/src/plugins/links/tsconfig.json b/src/plugins/links/tsconfig.json index e9814f4e107e..be7692c7fa43 100644 --- a/src/plugins/links/tsconfig.json +++ b/src/plugins/links/tsconfig.json @@ -26,7 +26,9 @@ "@kbn/logging", "@kbn/core-plugins-server", "@kbn/react-kibana-mount", - "@kbn/react-kibana-context-theme" + "@kbn/react-kibana-context-theme", + "@kbn/visualizations-plugin", + "@kbn/core-mount-utils-browser" ], "exclude": ["target/**/*"] } diff --git a/src/plugins/telemetry/server/fetcher.test.ts b/src/plugins/telemetry/server/fetcher.test.ts index e1da374dc723..5a61de1a0d83 100644 --- a/src/plugins/telemetry/server/fetcher.test.ts +++ b/src/plugins/telemetry/server/fetcher.test.ts @@ -195,6 +195,61 @@ describe('FetcherTask', () => { }) ); + test( + 'Retries when `getCurrentConfigs` rejects', + fakeSchedulers(async (advance) => { + expect(fetcherTask['isOnline$'].value).toBe(false); + getCurrentConfigs.mockRejectedValueOnce(new Error('SomeError')).mockResolvedValue({ + telemetryOptIn: true, + telemetrySendUsageFrom: 'server', + failureCount: 0, + telemetryUrl: 'test-url', + }); + fetchMock.mockResolvedValue({}); + + const subscription = fetcherTask['validateConnectivity'](); + + // need to advance / await twice for retry + advance(5 * 60 * 1000); + await new Promise((resolve) => process.nextTick(resolve)); // Wait for the initial promise to fulfill + advance(1 * 60 * 1000); + await new Promise((resolve) => process.nextTick(resolve)); // Wait for the retry promise to fulfill + + expect(getCurrentConfigs).toHaveBeenCalledTimes(2); + expect(fetchMock).toHaveBeenCalledTimes(1); + expect(updateReportFailure).toHaveBeenCalledTimes(0); + expect(fetcherTask['isOnline$'].value).toBe(true); + + subscription.unsubscribe(); + }) + ); + + test( + 'logs a message when retries are exceeded', + fakeSchedulers(async (advance) => { + expect(fetcherTask['isOnline$'].value).toBe(false); + getCurrentConfigs.mockRejectedValue(new Error('SomeError')); + + const subscription = fetcherTask['validateConnectivity'](); + + const wait = async () => { + advance(5 * 60 * 1000); + await new Promise((resolve) => process.nextTick(resolve)); // Wait for the initial promise to fulfill + }; + + for (let i = 0; i < 7; i++) { + await wait(); + } + + expect(fetcherTask['logger'].error).toBeCalledTimes(1); + expect(fetcherTask['logger'].error).toHaveBeenCalledWith( + `Cannot get the current config: SomeError` + ); + + subscription.unsubscribe(); + }) + ); + test( 'Should not retry if it hit the max number of failures for this version', fakeSchedulers(async (advance) => { diff --git a/src/plugins/telemetry/server/fetcher.ts b/src/plugins/telemetry/server/fetcher.ts index a79e04355177..756c9f49ded6 100644 --- a/src/plugins/telemetry/server/fetcher.ts +++ b/src/plugins/telemetry/server/fetcher.ts @@ -18,6 +18,10 @@ import { Subscription, takeUntil, timer, + catchError, + defer, + EMPTY, + retry, } from 'rxjs'; import fetch from 'node-fetch'; import type { TelemetryCollectionManagerPluginStart } from '@kbn/telemetry-collection-manager-plugin/server'; @@ -105,7 +109,25 @@ export class FetcherTask { // Skip any further processing if already online filter(() => !this.isOnline$.value), // Fetch current state and configs - exhaustMap(async () => await this.getCurrentConfigs()), + exhaustMap(() => { + return defer(() => { + return this.getCurrentConfigs(); + }).pipe( + // exp-backoff retries in case of errors fetching the config + retry({ + count: 5, + delay: (error, retryIndex) => { + const retryDelay = 1000 * Math.min(Math.pow(2, retryIndex + 2), 64); // 5 retries -> 8s, 16s, 32s, 64s, 64s + return timer(retryDelay); + }, + }), + // shallow errors if all retry failed, next time tick will continue the emission + catchError((err) => { + this.logger.error(`Cannot get the current config: ${err.message}`); + return EMPTY; + }) + ); + }), // Skip if opted-out, or should only send from the browser filter( ({ telemetryOptIn, telemetrySendUsageFrom }) => diff --git a/src/plugins/ui_actions/public/index.ts b/src/plugins/ui_actions/public/index.ts index ede7098b7e91..d996b6b4e2cd 100644 --- a/src/plugins/ui_actions/public/index.ts +++ b/src/plugins/ui_actions/public/index.ts @@ -31,14 +31,11 @@ export { visualizeGeoFieldTrigger, ROW_CLICK_TRIGGER, rowClickTrigger, - CATEGORIZE_FIELD_TRIGGER, - categorizeFieldTrigger, } from '@kbn/ui-actions-browser/src/triggers'; -export type { VisualizeFieldContext, CategorizeFieldContext } from './types'; +export type { VisualizeFieldContext } from './types'; export { ACTION_VISUALIZE_FIELD, ACTION_VISUALIZE_GEO_FIELD, ACTION_VISUALIZE_LENS_FIELD, - ACTION_CATEGORIZE_FIELD, } from './types'; export type { ActionExecutionContext, ActionExecutionMeta, ActionMenuItemProps } from './actions'; diff --git a/src/plugins/ui_actions/public/plugin.ts b/src/plugins/ui_actions/public/plugin.ts index 52629aa3f572..16060d4bf343 100644 --- a/src/plugins/ui_actions/public/plugin.ts +++ b/src/plugins/ui_actions/public/plugin.ts @@ -9,7 +9,6 @@ import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from '@kbn/core/public'; import { PublicMethodsOf } from '@kbn/utility-types'; import { - categorizeFieldTrigger, rowClickTrigger, visualizeFieldTrigger, visualizeGeoFieldTrigger, @@ -39,7 +38,6 @@ export class UiActionsPlugin implements Plugin { this.service.registerTrigger(rowClickTrigger); this.service.registerTrigger(visualizeFieldTrigger); this.service.registerTrigger(visualizeGeoFieldTrigger); - this.service.registerTrigger(categorizeFieldTrigger); return this.service; } diff --git a/src/plugins/ui_actions/public/types.ts b/src/plugins/ui_actions/public/types.ts index 6d689f6776d9..c66ea2b1769b 100644 --- a/src/plugins/ui_actions/public/types.ts +++ b/src/plugins/ui_actions/public/types.ts @@ -7,7 +7,7 @@ */ import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import type { AggregateQuery } from '@kbn/es-query'; -import type { DataViewField, DataViewSpec, DataView } from '@kbn/data-views-plugin/public'; +import type { DataViewSpec } from '@kbn/data-views-plugin/public'; import { ActionInternal } from './actions/action_internal'; import { TriggerInternal } from './triggers/trigger_internal'; @@ -24,13 +24,6 @@ export interface VisualizeFieldContext { query?: AggregateQuery; } -export interface CategorizeFieldContext { - field: DataViewField; - dataView: DataView; - originatingApp: string; -} - export const ACTION_VISUALIZE_FIELD = 'ACTION_VISUALIZE_FIELD'; export const ACTION_VISUALIZE_GEO_FIELD = 'ACTION_VISUALIZE_GEO_FIELD'; export const ACTION_VISUALIZE_LENS_FIELD = 'ACTION_VISUALIZE_LENS_FIELD'; -export const ACTION_CATEGORIZE_FIELD = 'ACTION_CATEGORIZE_FIELD'; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.test.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.test.tsx index fc8f7498f6ef..6c6ae2852e05 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.test.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.test.tsx @@ -12,13 +12,13 @@ import { getHeight } from './get_height'; describe('getHeight', () => { Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: 500 }); - const getMonacoMock = (lineCount: number) => { + const getMonacoMock = (lineCount: number, top: number = 200) => { return { getDomNode: jest.fn(() => { return { getBoundingClientRect: jest.fn(() => { return { - top: 200, + top, }; }), }; @@ -29,10 +29,17 @@ describe('getHeight', () => { } as unknown as monaco.editor.IStandaloneCodeEditor; }; test('when using document explorer, returning the available height in the flyout', () => { + const monacoMock = getMonacoMock(500, 0); + + const height = getHeight(monacoMock, true); + expect(height).toBe(475); + }); + + test('when using document explorer, returning the available height in the flyout has a minimun guarenteed height', () => { const monacoMock = getMonacoMock(500); const height = getHeight(monacoMock, true); - expect(height).toBe(275); + expect(height).toBe(400); }); test('when using classic table, its displayed inline without scrolling', () => { diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.tsx index 0dcabc8ae951..dbab289018a6 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/get_height.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ import { monaco } from '@kbn/monaco'; -import { MARGIN_BOTTOM, MAX_LINES_CLASSIC_TABLE } from './source'; +import { MARGIN_BOTTOM, MAX_LINES_CLASSIC_TABLE, MIN_HEIGHT } from './source'; export function getHeight(editor: monaco.editor.IStandaloneCodeEditor, useDocExplorer: boolean) { const editorElement = editor?.getDomNode(); @@ -28,5 +28,5 @@ export function getHeight(editor: monaco.editor.IStandaloneCodeEditor, useDocExp lineCount > MAX_LINES_CLASSIC_TABLE ? MAX_LINES_CLASSIC_TABLE : lineCount; result = editor.getTopForLineNumber(displayedLineCount + 1) + lineHeight; } - return result > 0 ? result : 0; + return Math.max(result, MIN_HEIGHT); } diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx index 26c771e405be..140fbd6e08cb 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_source/source.tsx @@ -36,6 +36,8 @@ interface SourceViewerProps { export const MAX_LINES_CLASSIC_TABLE = 500; // Displayed margin of the code editor to the window bottom when rendered in the document explorer flyout export const MARGIN_BOTTOM = 25; +// Minimum height for the source content to guarantee minimum space when the flyout is scrollable. +export const MIN_HEIGHT = 400; export const DocViewerSource = ({ id, diff --git a/src/plugins/unified_histogram/public/chart/chart.tsx b/src/plugins/unified_histogram/public/chart/chart.tsx index 42f3d5658478..a64944d73b5f 100644 --- a/src/plugins/unified_histogram/public/chart/chart.tsx +++ b/src/plugins/unified_histogram/public/chart/chart.tsx @@ -76,6 +76,7 @@ export interface ChartProps { lensAdapters?: UnifiedHistogramChartLoadEvent['adapters']; lensEmbeddableOutput$?: Observable; isOnHistogramMode?: boolean; + histogramQuery?: AggregateQuery; isChartLoading?: boolean; onResetChartHeight?: () => void; onChartHiddenChange?: (chartHidden: boolean) => void; @@ -115,6 +116,7 @@ export function Chart({ lensAdapters, lensEmbeddableOutput$, isOnHistogramMode, + histogramQuery, isChartLoading, onResetChartHeight, onChartHiddenChange, @@ -216,7 +218,7 @@ export function Chart({ getLensAttributes({ title: chart?.title, filters, - query, + query: histogramQuery ?? query, dataView, timeInterval: chart?.timeInterval, breakdownField: breakdown?.field, @@ -230,6 +232,7 @@ export function Chart({ dataView, filters, query, + histogramQuery, ] ); diff --git a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx index 486ea7da7987..5ed329f251a9 100644 --- a/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx +++ b/src/plugins/unified_histogram/public/chart/chart_config_panel.tsx @@ -68,6 +68,7 @@ export function ChartConfigPanel({ updatePanelState={updateSuggestion} lensAdapters={lensAdapters} output$={lensEmbeddableOutput$} + displayFlyoutHeader closeFlyout={() => { setIsFlyoutVisible(false); }} diff --git a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.test.ts b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.test.ts index d891c62df351..7bd7e6f21ed5 100644 --- a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.test.ts +++ b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.test.ts @@ -38,6 +38,7 @@ describe('useLensSuggestions', () => { allSuggestions: [], currentSuggestion: undefined, isOnHistogramMode: false, + histogramQuery: undefined, suggestionUnsupported: false, }); }); @@ -66,6 +67,7 @@ describe('useLensSuggestions', () => { allSuggestions: allSuggestionsMock, currentSuggestion: allSuggestionsMock[0], isOnHistogramMode: false, + histogramQuery: undefined, suggestionUnsupported: false, }); }); @@ -94,6 +96,7 @@ describe('useLensSuggestions', () => { allSuggestions: [], currentSuggestion: undefined, isOnHistogramMode: false, + histogramQuery: undefined, suggestionUnsupported: true, }); }); @@ -133,6 +136,9 @@ describe('useLensSuggestions', () => { allSuggestions: [], currentSuggestion: allSuggestionsMock[0], isOnHistogramMode: true, + histogramQuery: { + esql: 'from the-data-view | limit 100 | EVAL timestamp=DATE_TRUNC(30 minute, @timestamp) | stats rows = count(*) by timestamp | rename timestamp as `@timestamp every 30 minute`', + }, suggestionUnsupported: false, }); }); @@ -172,6 +178,7 @@ describe('useLensSuggestions', () => { allSuggestions: [], currentSuggestion: undefined, isOnHistogramMode: false, + histogramQuery: undefined, suggestionUnsupported: true, }); }); diff --git a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts index 514c32cefcb8..5441e08a28c7 100644 --- a/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts +++ b/src/plugins/unified_histogram/public/layout/hooks/use_lens_suggestions.ts @@ -61,7 +61,7 @@ export const useLensSuggestions = ({ const [allSuggestions, setAllSuggestions] = useState(suggestions.allSuggestions); const currentSuggestion = originalSuggestion ?? suggestions.firstSuggestion; const suggestionDeps = useRef(getSuggestionDeps({ dataView, query, columns })); - + const histogramQuery = useRef(); const histogramSuggestion = useMemo(() => { if ( !currentSuggestion && @@ -85,8 +85,7 @@ export const useLensSuggestions = ({ const interval = computeInterval(timeRange, data); const language = getAggregateQueryMode(query); - const histogramQuery = `${query[language]} - | EVAL timestamp=DATE_TRUNC(${interval}, ${dataView.timeFieldName}) | stats rows = count(*) by timestamp | rename timestamp as \`${dataView.timeFieldName} every ${interval}\``; + const esqlQuery = `${query[language]} | EVAL timestamp=DATE_TRUNC(${interval}, ${dataView.timeFieldName}) | stats rows = count(*) by timestamp | rename timestamp as \`${dataView.timeFieldName} every ${interval}\``; const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', @@ -107,15 +106,16 @@ export const useLensSuggestions = ({ }, ] as DatatableColumn[], query: { - esql: histogramQuery, + esql: esqlQuery, }, }; const sug = lensSuggestionsApi(context, dataView, ['lnsDatatable']) ?? []; if (sug.length) { + histogramQuery.current = { esql: esqlQuery }; return sug[0]; } - return undefined; } + histogramQuery.current = undefined; return undefined; }, [currentSuggestion, dataView, query, timeRange, data, lensSuggestionsApi]); @@ -142,6 +142,7 @@ export const useLensSuggestions = ({ currentSuggestion: histogramSuggestion ?? currentSuggestion, suggestionUnsupported: !currentSuggestion && !histogramSuggestion && isPlainRecord, isOnHistogramMode: Boolean(histogramSuggestion), + histogramQuery: histogramQuery.current ? histogramQuery.current : undefined, }; }; diff --git a/src/plugins/unified_histogram/public/layout/layout.tsx b/src/plugins/unified_histogram/public/layout/layout.tsx index d923ea3031a5..17eaf65fcde5 100644 --- a/src/plugins/unified_histogram/public/layout/layout.tsx +++ b/src/plugins/unified_histogram/public/layout/layout.tsx @@ -215,18 +215,23 @@ export const UnifiedHistogramLayout = ({ children, withDefaultActions, }: UnifiedHistogramLayoutProps) => { - const { allSuggestions, currentSuggestion, suggestionUnsupported, isOnHistogramMode } = - useLensSuggestions({ - dataView, - query, - originalSuggestion, - isPlainRecord, - columns, - timeRange, - data: services.data, - lensSuggestionsApi, - onSuggestionChange, - }); + const { + allSuggestions, + currentSuggestion, + suggestionUnsupported, + isOnHistogramMode, + histogramQuery, + } = useLensSuggestions({ + dataView, + query, + originalSuggestion, + isPlainRecord, + columns, + timeRange, + data: services.data, + lensSuggestionsApi, + onSuggestionChange, + }); const chart = suggestionUnsupported ? undefined : originalChart; const [topPanelNode] = useState(() => @@ -302,6 +307,7 @@ export const UnifiedHistogramLayout = ({ lensAdapters={lensAdapters} lensEmbeddableOutput$={lensEmbeddableOutput$} isOnHistogramMode={isOnHistogramMode} + histogramQuery={histogramQuery} withDefaultActions={withDefaultActions} /> diff --git a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx index e1565f1ff6b0..8c35ed21568b 100644 --- a/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx +++ b/src/plugins/unified_search/public/dataview_picker/change_dataview.tsx @@ -215,7 +215,7 @@ export function ChangeDataView({ })} ) : ( - + ), ); @@ -336,7 +336,7 @@ export function ChangeDataView({ if (textBasedLanguages?.length) { panelItems.push( , - + { { id: 'wat', image: undefined, + editor: { + editUrl: '/edit/wat', + }, readOnly: false, references: undefined, icon: undefined, savedObjectType: 'visualization', - editUrl: '/edit/wat', type: 'test', typeName: 'test', typeTitle: undefined, diff --git a/src/plugins/visualizations/public/utils/saved_visualize_utils.ts b/src/plugins/visualizations/public/utils/saved_visualize_utils.ts index 9232504e026d..85932c09729c 100644 --- a/src/plugins/visualizations/public/utils/saved_visualize_utils.ts +++ b/src/plugins/visualizations/public/utils/saved_visualize_utils.ts @@ -73,7 +73,7 @@ export function mapHitSource( references: SavedObjectReference[]; url: string; savedObjectType?: string; - editUrl?: string; + editor?: { editUrl?: string }; updatedAt?: string; type?: BaseVisType; icon?: BaseVisType['icon']; @@ -108,7 +108,7 @@ export function mapHitSource( newAttributes.icon = newAttributes.type?.icon; newAttributes.image = newAttributes.type?.image; newAttributes.typeTitle = newAttributes.type?.title; - newAttributes.editUrl = `/edit/${id}`; + newAttributes.editor = { editUrl: `/edit/${id}` }; newAttributes.readOnly = Boolean(visTypes.get(typeName as string)?.disableEdit); return newAttributes; @@ -168,7 +168,6 @@ export async function findListItems( return acc; }, acc); }, {} as { [visType: string]: VisualizationsAppExtension }); - const searchOption = (field: string, ...defaults: string[]) => _(extensions).map(field).concat(defaults).compact().flatten().uniq().value() as string[]; diff --git a/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts b/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts index 2a46b28f06dd..617f0386f618 100644 --- a/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts +++ b/src/plugins/visualizations/public/vis_types/vis_type_alias_registry.ts @@ -19,8 +19,6 @@ import { BaseVisType } from './base_vis_type'; export type VisualizationStage = 'experimental' | 'beta' | 'production'; export interface VisualizationListItem { - editUrl: string; - editApp?: string; error?: string; icon: string; id: string; @@ -32,6 +30,9 @@ export interface VisualizationListItem { typeTitle: string; image?: string; type?: BaseVisType | string; + editor: + | { editUrl: string; editApp?: string } + | { onEdit: (savedObjectId: string) => Promise }; } export interface SerializableAttributes { @@ -86,8 +87,14 @@ export interface VisualizationsAppExtension { } export interface VisTypeAlias { - aliasPath: string; - aliasApp: string; + /** + * Provide `alias` when your visualization has a dedicated app for creation. + * TODO: Provide a generic callback to create visualizations inline. + */ + alias?: { + app: string; + path: string; + }; name: string; title: string; icon: string; diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.scss b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.scss index 7fe4fe05ab26..48df3fc67388 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.scss +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.scss @@ -11,7 +11,7 @@ .visListingTable__experimentalIcon { width: $euiSizeL; - vertical-align: baseline; + vertical-align: middle; padding: 0 $euiSizeS; margin-left: $euiSizeS; } diff --git a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx index d4beb45c4e24..d1de28ac7379 100644 --- a/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx +++ b/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx @@ -36,6 +36,7 @@ import { TableListViewProps, } from '@kbn/content-management-table-list-view'; import { TableListViewTable } from '@kbn/content-management-table-list-view-table'; + import { findListItems } from '../../utils/saved_visualize_utils'; import { updateBasicSoAttributes } from '../../utils/saved_objects_utils/update_basic_attributes'; import { checkForDuplicateTitle } from '../../utils/saved_objects_utils/check_for_duplicate_title'; @@ -49,17 +50,17 @@ import { getNoItemsMessage, getCustomColumn } from '../utils'; import { getVisualizeListItemLink } from '../utils/get_visualize_list_item_link'; import type { VisualizationStage } from '../../vis_types/vis_type_alias_registry'; -interface VisualizeUserContent extends VisualizationListItem, UserContentCommonSchema { - type: string; - attributes: { - title: string; - description?: string; - editApp: string; - editUrl: string; - readOnly: boolean; - error?: string; +type VisualizeUserContent = VisualizationListItem & + UserContentCommonSchema & { + type: string; + attributes: { + id: string; + title: string; + description?: string; + readOnly: boolean; + error?: string; + }; }; -} const toTableListViewSavedObject = (savedObject: Record): VisualizeUserContent => { return { @@ -67,19 +68,17 @@ const toTableListViewSavedObject = (savedObject: Record): Visua updatedAt: savedObject.updatedAt as string, references: savedObject.references as Array<{ id: string; type: string; name: string }>, type: savedObject.savedObjectType as string, - editUrl: savedObject.editUrl as string, - editApp: savedObject.editApp as string, icon: savedObject.icon as string, stage: savedObject.stage as VisualizationStage, savedObjectType: savedObject.savedObjectType as string, typeTitle: savedObject.typeTitle as string, title: (savedObject.title as string) ?? '', error: (savedObject.error as string) ?? '', + editor: savedObject.editor as any, attributes: { + id: savedObject.id as string, title: (savedObject.title as string) ?? '', description: savedObject.description as string, - editApp: savedObject.editApp as string, - editUrl: savedObject.editUrl as string, readOnly: savedObject.readOnly as boolean, error: savedObject.error as string, }, @@ -120,7 +119,13 @@ const useTableListViewProps = ( }, [closeNewVisModal]); const editItem = useCallback( - ({ attributes: { editUrl, editApp } }: VisualizeUserContent) => { + async ({ attributes: { id }, editor }: VisualizeUserContent) => { + if (!('editApp' in editor || 'editUrl' in editor)) { + await editor.onEdit(id); + return; + } + + const { editApp, editUrl } = editor; if (editApp) { application.navigateToApp(editApp, { path: editUrl }); return; @@ -383,10 +388,19 @@ export const VisualizeListing = () => { entityNamePlural={i18n.translate('visualizations.listing.table.entityNamePlural', { defaultMessage: 'visualizations', })} - getDetailViewLink={({ attributes: { editApp, editUrl, error, readOnly } }) => - readOnly + onClickTitle={(item) => { + tableViewProps.editItem?.(item); + }} + getDetailViewLink={({ editor, attributes: { error, readOnly } }) => + readOnly || (editor && 'onEdit' in editor) ? undefined - : getVisualizeListItemLink(application, kbnUrlStateStorage, editApp, editUrl, error) + : getVisualizeListItemLink( + application, + kbnUrlStateStorage, + editor.editApp, + editor.editUrl, + error + ) } tableCaption={visualizeLibraryTitle} {...tableViewProps} diff --git a/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.ts b/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.ts index 524ccbad44f8..5c1a5b1ee3eb 100644 --- a/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.ts +++ b/src/plugins/visualizations/public/visualize_app/utils/get_visualize_list_item_link.ts @@ -17,10 +17,10 @@ export const getVisualizeListItemLink = ( application: ApplicationStart, kbnUrlStateStorage: IKbnUrlStateStorage, editApp: string | undefined, - editUrl: string, + editUrl: string | undefined, error: string | undefined = undefined ) => { - if (error) { + if (error || (!editApp && !editUrl)) { return undefined; } diff --git a/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx b/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx index e1e9cec25e15..a9a21446e06a 100644 --- a/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx +++ b/src/plugins/visualizations/public/wizard/group_selection/group_selection.test.tsx @@ -37,8 +37,10 @@ describe('GroupSelection', () => { { name: 'visWithAliasUrl', title: 'Vis with alias Url', - aliasApp: 'aliasApp', - aliasPath: '#/aliasApp', + alias: { + app: 'aliasApp', + path: '#/aliasApp', + }, description: 'Vis with alias Url', stage: 'production', group: VisGroups.PROMOTED, @@ -49,8 +51,10 @@ describe('GroupSelection', () => { description: 'Vis alias with promotion', stage: 'production', group: VisGroups.PROMOTED, - aliasApp: 'anotherApp', - aliasPath: '#/anotherUrl', + alias: { + app: 'anotherApp', + path: '#/anotherUrl', + }, promotion: true, } as unknown, ] as BaseVisType[]; diff --git a/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx b/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx index dc8aaa03161b..3bcdff18c47a 100644 --- a/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx +++ b/src/plugins/visualizations/public/wizard/group_selection/group_selection.tsx @@ -200,7 +200,7 @@ const VisGroup = ({ visType, onVisTypeSelected }: VisCardProps) => { } onClick={onClick} data-test-subj={`visType-${visType.name}`} - data-vis-stage={!('aliasPath' in visType) ? visType.stage : 'alias'} + data-vis-stage={!('alias' in visType) ? visType.stage : 'alias'} aria-label={`visType-${visType.name}`} description={ <> diff --git a/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx b/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx index 907c989c7bb4..0db5f66cc5c9 100644 --- a/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx +++ b/src/plugins/visualizations/public/wizard/new_vis_modal.test.tsx @@ -47,8 +47,10 @@ describe('NewVisModal', () => { title: 'Vis with alias Url', stage: 'production', group: VisGroups.PROMOTED, - aliasApp: 'otherApp', - aliasPath: '#/aliasUrl', + alias: { + app: 'otherApp', + path: '#/aliasUrl', + }, }, { name: 'visWithSearch', @@ -181,7 +183,7 @@ describe('NewVisModal', () => { ); }); - it('closes and redirects properly if visualization with aliasPath and originatingApp in props', () => { + it('closes and redirects properly if visualization with alias.path and originatingApp in props', () => { const onClose = jest.fn(); const navigateToApp = jest.fn(); const stateTransfer = embeddablePluginMock.createStartContract().getStateTransfer(); diff --git a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx index ac1f89e73700..b1e5de321526 100644 --- a/src/plugins/visualizations/public/wizard/new_vis_modal.tsx +++ b/src/plugins/visualizations/public/wizard/new_vis_modal.tsx @@ -119,7 +119,7 @@ class NewVisModal extends React.Component { - if (!('aliasPath' in visType) && visType.requiresSearch && visType.options.showIndexSelection) { + if ('visConfig' in visType && visType.requiresSearch && visType.options.showIndexSelection) { this.setState({ showSearchVisModal: true, visType, @@ -143,10 +143,12 @@ class NewVisModal extends React.Component { this.log.debug(`click "${name}" app link`); - await this.openCollapsibleNav(); - let nav; - if (typeof category === 'string') { - nav = await this.testSubjects.find(`collapsibleNavGroup-${category}`); - } else { - nav = await this.testSubjects.find('collapsibleNav'); - } - const link = await nav.findByPartialLinkText(name); - await link.click(); - if (closeCollapsibleNav) { - await this.closeCollapsibleNav(); + try { + await this.openCollapsibleNav(); + let nav; + if (typeof category === 'string') { + // we can search within a specific section of the side nav + nav = await this.testSubjects.find(`collapsibleNavGroup-${category}`); + const link = await nav.findByPartialLinkText(name); + await link.click(); + } else { + // we need to search our app link in the whole side nav + // first, we get all the links, along with their inner text + const allLinks = await this.testSubjects.findAll('collapsibleNavAppLink'); + const allLinksTexts = await Promise.all( + allLinks.map((link) => link.getVisibleText().then((text) => ({ link, text }))) + ); + + // then, filter out those that don't have a matching text + const matchingLinks = allLinksTexts.filter(({ text }) => text.includes(name)); + if (matchingLinks.length === 0) { + this.log.debug( + `Found ${allLinks.length} links on the side nav: ${allLinksTexts.map( + ({ text }) => text + )}` + ); + throw new Error( + `Could not find the '${name}' application on the side nav (${allLinks.length} links found)` + ); + } else if (matchingLinks.length > 1) { + throw new Error( + `Multiple apps exist in the side nav with the specified name: '${name}'. Consider using the "category" parameter to disambiguate` + ); + } + + this.log.debug(`Found "${name}" app link on the side nav!`); + // if we click on a stale element (e.g. re-rendered) it'll throw an Error and we will retry + await matchingLinks.pop()!.link.click(); + } + + if (closeCollapsibleNav) { + await this.closeCollapsibleNav(); + } + } finally { + // Intentionally empty } - } finally { - // Intentionally empty - } + }); } } diff --git a/test/plugin_functional/plugins/core_plugin_route_timeouts/server/plugin.ts b/test/plugin_functional/plugins/core_plugin_route_timeouts/server/plugin.ts index fce258c1b8b0..5ecdc0a03dd0 100644 --- a/test/plugin_functional/plugins/core_plugin_route_timeouts/server/plugin.ts +++ b/test/plugin_functional/plugins/core_plugin_route_timeouts/server/plugin.ts @@ -53,7 +53,7 @@ export class CorePluginRouteTimeoutsPlugin implements Plugin { body: { accepts: ['application/json'], }, - timeout: { idleSocket: 10 }, + timeout: { idleSocket: 5 }, }, path: '/short_idle_socket_timeout', validate: { diff --git a/test/plugin_functional/test_suites/core/route.ts b/test/plugin_functional/test_suites/core/route.ts index 13bd4190d32f..597189dd5faf 100644 --- a/test/plugin_functional/test_suites/core/route.ts +++ b/test/plugin_functional/test_suites/core/route.ts @@ -7,14 +7,13 @@ */ import expect from '@kbn/expect'; -import { Test } from 'supertest'; -import { PluginFunctionalProviderContext } from '../../services'; +import type { Test } from 'supertest'; +import type { PluginFunctionalProviderContext } from '../../services'; export default function ({ getService }: PluginFunctionalProviderContext) { const supertest = getService('supertest'); - // FLAKY: https://github.com/elastic/kibana/issues/75440 - describe.skip('route', function () { + describe('route', function () { describe('timeouts', function () { const writeBodyCharAtATime = (request: Test, body: string, interval: number) => { return new Promise((resolve, reject) => { @@ -45,7 +44,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { .set('Transfer-Encoding', 'chunked') .set('kbn-xsrf', 'true'); - const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 10); + const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 20); await result.then( (res) => { @@ -65,7 +64,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { .set('Transfer-Encoding', 'chunked') .set('kbn-xsrf', 'true'); - const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 10); + const result = writeBodyCharAtATime(request, '{"foo":"bar"}', 20); await result.then( (res) => { @@ -107,7 +106,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { .set('Transfer-Encoding', 'chunked') .set('kbn-xsrf', 'true'); - const result = writeBodyCharAtATime(request, '{"responseDelay":0}', 10); + const result = writeBodyCharAtATime(request, '{"responseDelay":0}', 20); await result.then( (res) => { @@ -119,44 +118,23 @@ export default function ({ getService }: PluginFunctionalProviderContext) { ); }); - it('should timeout if servers response is too slow', async function () { - // start the request - const request = supertest + it('should timeout if servers response is too slow', async () => { + await supertest .post('/short_idle_socket_timeout') + .send({ responseDelay: 100 }) .set('Content-Type', 'application/json') - .set('Transfer-Encoding', 'chunked') - .set('kbn-xsrf', 'true'); - - const result = writeBodyCharAtATime(request, '{"responseDelay":100}', 0); - - await result.then( - (res) => { - expect(res).to.be(undefined); - }, - (err) => { - expect(err.message).to.be('socket hang up'); - } - ); + .set('kbn-xsrf', 'true') + .then(() => expect('to throw').to.be('but it did NOT')) + .catch((error) => expect(error.message).to.be('socket hang up')); }); - it('should not timeout if servers response is fast enough', async function () { - // start the request - const request = supertest + it('should not timeout if servers response is fast enough', async () => { + await supertest .post('/longer_idle_socket_timeout') + .send({ responseDelay: 100 }) .set('Content-Type', 'application/json') - .set('Transfer-Encoding', 'chunked') - .set('kbn-xsrf', 'true'); - - const result = writeBodyCharAtATime(request, '{"responseDelay":100}', 0); - - await result.then( - (res) => { - expect(res).to.have.property('statusCode', 200); - }, - (err) => { - expect(err).to.be(undefined); - } - ); + .set('kbn-xsrf', 'true') + .expect(200); }); }); }); diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts index 862cb6acfb6d..d33000bfa70c 100644 --- a/test/plugin_functional/test_suites/core_plugins/applications.ts +++ b/test/plugin_functional/test_suites/core_plugins/applications.ts @@ -7,7 +7,7 @@ */ import expect from '@kbn/expect'; -import { PluginFunctionalProviderContext } from '../../services'; +import type { PluginFunctionalProviderContext } from '../../services'; export default function ({ getService, getPageObject }: PluginFunctionalProviderContext) { const common = getPageObject('common'); @@ -17,10 +17,24 @@ export default function ({ getService, getPageObject }: PluginFunctionalProvider const find = getService('find'); const deployment = getService('deployment'); const esArchiver = getService('esArchiver'); + const log = getService('log'); + + const clickAppLink = async (app: string) => { + const appLink = `fooNav${app}`; + if (!(await testSubjects.exists(appLink))) { + log.debug(`App ${app} not found on side nav`); + } + await testSubjects.click(appLink); + }; const loadingScreenNotShown = async () => expect(await testSubjects.exists('kbnLoadingMessage')).to.be(false); + const checkAppVisible = async (app: string) => { + const appContainer = `fooApp${app}`; + await testSubjects.existOrFail(appContainer); + }; + const getAppWrapperHeight = async () => { const wrapper = await find.byClassName('kbnAppWrapper'); return (await wrapper.getSize()).height; @@ -29,8 +43,7 @@ export default function ({ getService, getPageObject }: PluginFunctionalProvider const navigateTo = async (path: string) => await browser.navigateTo(`${deployment.getHostPort()}${path}`); - // FLAKY: https://github.com/elastic/kibana/issues/53356 - describe.skip('ui applications', function describeIndexTests() { + describe('ui applications', function describeIndexTests() { before(async () => { await esArchiver.emptyKibanaIndex(); await common.navigateToApp('foo'); @@ -38,48 +51,48 @@ export default function ({ getService, getPageObject }: PluginFunctionalProvider }); it('starts on home page', async () => { - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); }); it('redirects and renders correctly regardless of trailing slash', async () => { await navigateTo(`/app/foo`); await browser.waitForUrlToBe('/app/foo/home'); - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); await navigateTo(`/app/foo/`); await browser.waitForUrlToBe('/app/foo/home'); - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); }); it('navigates to its own pages', async () => { // Go to page A - await testSubjects.click('fooNavPageA'); + await clickAppLink('PageA'); await browser.waitForUrlToBe('/app/foo/page-a'); await loadingScreenNotShown(); - await testSubjects.existOrFail('fooAppPageA'); + await checkAppVisible('PageA'); // Go to home page - await testSubjects.click('fooNavHome'); + await clickAppLink('Home'); await browser.waitForUrlToBe('/app/foo/home'); await loadingScreenNotShown(); - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); }); it('can use the back button to navigate within an app', async () => { await browser.goBack(); await browser.waitForUrlToBe('/app/foo/page-a'); await loadingScreenNotShown(); - await testSubjects.existOrFail('fooAppPageA'); + await checkAppVisible('PageA'); }); it('navigates to app root when navlink is clicked', async () => { - await appsMenu.clickLink('Foo', { category: 'kibana' }); + await appsMenu.clickLink('Foo'); await browser.waitForUrlToBe('/app/foo/home'); await loadingScreenNotShown(); - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); }); it('navigates to other apps', async () => { - await testSubjects.click('fooNavBarPageB'); + await clickAppLink('BarPageB'); await loadingScreenNotShown(); await testSubjects.existOrFail('barAppPageB'); await browser.waitForUrlToBe('/app/bar/page-b?query=here'); @@ -94,7 +107,7 @@ export default function ({ getService, getPageObject }: PluginFunctionalProvider await browser.goBack(); await browser.waitForUrlToBe('/app/foo/home'); await loadingScreenNotShown(); - await testSubjects.existOrFail('fooAppHome'); + await checkAppVisible('Home'); }); it('chromeless applications are not visible in apps list', async () => { diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index dc6ff1211eb9..8b248c5bccc6 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -283,6 +283,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.infra.featureFlags.logThresholdAlertRuleEnabled (any)', 'xpack.infra.featureFlags.logsUIEnabled (any)', 'xpack.infra.featureFlags.alertsAndRulesDropdownEnabled (any)', + 'xpack.infra.featureFlags.profilingEnabled (any)', 'xpack.license_management.ui.enabled (boolean)', 'xpack.maps.preserveDrawingBuffer (boolean)', diff --git a/tsconfig.base.json b/tsconfig.base.json index 06ade5904efa..d21fd5f4359a 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1066,8 +1066,12 @@ "@kbn/ml-string-hash/*": ["x-pack/packages/ml/string_hash/*"], "@kbn/ml-trained-models-utils": ["x-pack/packages/ml/trained_models_utils"], "@kbn/ml-trained-models-utils/*": ["x-pack/packages/ml/trained_models_utils/*"], + "@kbn/ml-ui-actions": ["x-pack/packages/ml/ui_actions"], + "@kbn/ml-ui-actions/*": ["x-pack/packages/ml/ui_actions/*"], "@kbn/ml-url-state": ["x-pack/packages/ml/url_state"], "@kbn/ml-url-state/*": ["x-pack/packages/ml/url_state/*"], + "@kbn/mock-idp-plugin": ["packages/kbn-mock-idp-plugin"], + "@kbn/mock-idp-plugin/*": ["packages/kbn-mock-idp-plugin/*"], "@kbn/monaco": ["packages/kbn-monaco"], "@kbn/monaco/*": ["packages/kbn-monaco/*"], "@kbn/monitoring-collection-plugin": ["x-pack/plugins/monitoring_collection"], @@ -1496,8 +1500,6 @@ "@kbn/stdio-dev-helpers/*": ["packages/kbn-stdio-dev-helpers/*"], "@kbn/storybook": ["packages/kbn-storybook"], "@kbn/storybook/*": ["packages/kbn-storybook/*"], - "@kbn/subscription-tracking": ["packages/kbn-subscription-tracking"], - "@kbn/subscription-tracking/*": ["packages/kbn-subscription-tracking/*"], "@kbn/synthetics-plugin": ["x-pack/plugins/synthetics"], "@kbn/synthetics-plugin/*": ["x-pack/plugins/synthetics/*"], "@kbn/task-manager-fixture-plugin": ["x-pack/test/alerting_api_integration/common/plugins/task_manager_fixture"], @@ -1676,9 +1678,7 @@ "@kbn/zod-helpers/*": ["packages/kbn-zod-helpers/*"], // END AUTOMATED PACKAGE LISTING // Allows for importing from `kibana` package for the exported types. - "@emotion/core": [ - "typings/@emotion" - ], + "@emotion/core": ["typings/@emotion"] }, // Support .tsx files and transform JSX into calls to React.createElement "jsx": "react", @@ -1749,6 +1749,6 @@ "@kbn/ambient-ui-types", "@kbn/ambient-common-types", "@kbn/ambient-storybook-types" - ], + ] } } diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json index bb14c06a53e3..45bf932799b3 100644 --- a/x-pack/.i18nrc.json +++ b/x-pack/.i18nrc.json @@ -59,6 +59,7 @@ "packages/ml/date_picker", "packages/ml/trained_models_utils", "packages/ml/category_validator", + "packages/ml/ui_actions", "plugins/ml" ], "xpack.monitoring": ["plugins/monitoring"], diff --git a/x-pack/packages/ml/aiops_utils/window_parameters.ts b/x-pack/packages/ml/aiops_utils/window_parameters.ts index 806d224defdf..91ecee5f841a 100644 --- a/x-pack/packages/ml/aiops_utils/window_parameters.ts +++ b/x-pack/packages/ml/aiops_utils/window_parameters.ts @@ -15,25 +15,13 @@ import { isPopulatedObject } from '@kbn/ml-is-populated-object'; * @typedef {WindowParameters} */ export interface WindowParameters { - /** - * Baseline minimum value - * @type {number} - */ + /** Baseline minimum value */ baselineMin: number; - /** - * Baseline maximum value - * @type {number} - */ + /** Baseline maximum value */ baselineMax: number; - /** - * Deviation minimum value - * @type {number} - */ + /** Deviation minimum value */ deviationMin: number; - /** - * Deviation maximum value - * @type {number} - */ + /** Deviation maximum value */ deviationMax: number; } diff --git a/x-pack/packages/ml/data_grid/index.ts b/x-pack/packages/ml/data_grid/index.ts index 129feadb00ca..49468ce79c51 100644 --- a/x-pack/packages/ml/data_grid/index.ts +++ b/x-pack/packages/ml/data_grid/index.ts @@ -10,7 +10,7 @@ export { getDataGridSchemaFromESFieldType, getDataGridSchemaFromKibanaFieldType, getFeatureImportance, - getFieldsFromKibanaIndexPattern, + getFieldsFromKibanaDataView, getNestedOrEscapedVal, getProcessedFields, getTopClasses, diff --git a/x-pack/packages/ml/data_grid/lib/common.ts b/x-pack/packages/ml/data_grid/lib/common.ts index 3b6e8dc4dad6..84dc4591d9a1 100644 --- a/x-pack/packages/ml/data_grid/lib/common.ts +++ b/x-pack/packages/ml/data_grid/lib/common.ts @@ -83,7 +83,7 @@ export const euiDataGridToolbarSettings = { * @param {DataView} dataView - The Kibana data view. * @returns {string[]} - The array of field names from the data view. */ -export const getFieldsFromKibanaIndexPattern = (dataView: DataView): string[] => { +export const getFieldsFromKibanaDataView = (dataView: DataView): string[] => { const allFields = dataView.fields.map((f) => f.name); const dataViewFields: string[] = allFields.filter((f) => { if (dataView.metaFields.includes(f)) { diff --git a/x-pack/packages/ml/data_grid/lib/types.ts b/x-pack/packages/ml/data_grid/lib/types.ts index 2c1ab284d1c2..2d8ed5319237 100644 --- a/x-pack/packages/ml/data_grid/lib/types.ts +++ b/x-pack/packages/ml/data_grid/lib/types.ts @@ -158,9 +158,9 @@ export interface UseIndexDataReturnType */ renderCellValue: RenderCellValue; /** - * Optional index pattern fields. + * Optional data view fields. */ - indexPatternFields?: string[]; + dataViewFields?: string[]; /** * Optional time range. */ 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 5b2a9d880c1b..cb890172bbdd 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 @@ -7,7 +7,7 @@ import React, { FC, useCallback, useMemo, useState } from 'react'; -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { EuiButton, diff --git a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts index cfd363e8b53c..c4cdd23995ae 100644 --- a/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts +++ b/x-pack/packages/ml/date_picker/src/services/full_time_range_selector_service.ts @@ -8,7 +8,7 @@ import moment from 'moment'; import type { TimefilterContract } from '@kbn/data-plugin/public'; import dateMath from '@kbn/datemath'; -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { i18n } from '@kbn/i18n'; import type { ToastsStart, HttpStart } from '@kbn/core/public'; import type { DataView } from '@kbn/data-views-plugin/public'; diff --git a/x-pack/packages/ml/date_picker/src/services/time_field_range.ts b/x-pack/packages/ml/date_picker/src/services/time_field_range.ts index 07a5fb3de355..92d71f582a1e 100644 --- a/x-pack/packages/ml/date_picker/src/services/time_field_range.ts +++ b/x-pack/packages/ml/date_picker/src/services/time_field_range.ts @@ -6,7 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import type { HttpStart } from '@kbn/core/public'; diff --git a/x-pack/packages/ml/query_utils/src/add_exclude_frozen_to_query.ts b/x-pack/packages/ml/query_utils/src/add_exclude_frozen_to_query.ts index 716254603496..3148e93bed02 100644 --- a/x-pack/packages/ml/query_utils/src/add_exclude_frozen_to_query.ts +++ b/x-pack/packages/ml/query_utils/src/add_exclude_frozen_to_query.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { cloneDeep } from 'lodash'; import { isPopulatedObject } from '@kbn/ml-is-populated-object'; diff --git a/x-pack/packages/ml/ui_actions/README.md b/x-pack/packages/ml/ui_actions/README.md new file mode 100644 index 000000000000..a9cba4a278c8 --- /dev/null +++ b/x-pack/packages/ml/ui_actions/README.md @@ -0,0 +1,3 @@ +# @kbn/ml-ui-actions + +Empty package generated by @kbn/generate diff --git a/x-pack/packages/ml/ui_actions/index.ts b/x-pack/packages/ml/ui_actions/index.ts new file mode 100644 index 000000000000..7a82ca6d68d9 --- /dev/null +++ b/x-pack/packages/ml/ui_actions/index.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION, + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, + type CreateCategorizationADJobContext, +} from './src/ml/ui_actions'; + +export { + ACTION_CATEGORIZE_FIELD, + CATEGORIZE_FIELD_TRIGGER, + categorizeFieldTrigger, + type CategorizeFieldContext, +} from './src/aiops/ui_actions'; diff --git a/x-pack/plugins/apm/common/utils/to_kuery_filter_format.ts b/x-pack/packages/ml/ui_actions/jest.config.js similarity index 57% rename from x-pack/plugins/apm/common/utils/to_kuery_filter_format.ts rename to x-pack/packages/ml/ui_actions/jest.config.js index 8e3169f4d07e..8efadb42705f 100644 --- a/x-pack/plugins/apm/common/utils/to_kuery_filter_format.ts +++ b/x-pack/packages/ml/ui_actions/jest.config.js @@ -5,10 +5,8 @@ * 2.0. */ -export function toKueryFilterFormat( - key: string, - values: string[], - separator: 'OR' | 'AND' = 'OR' -) { - return values.map((value) => `${key} : "${value}"`).join(` ${separator} `); -} +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../../../..', + roots: ['/x-pack/packages/ml/ui_actions'], +}; diff --git a/x-pack/packages/ml/ui_actions/kibana.jsonc b/x-pack/packages/ml/ui_actions/kibana.jsonc new file mode 100644 index 000000000000..999f955bc2e4 --- /dev/null +++ b/x-pack/packages/ml/ui_actions/kibana.jsonc @@ -0,0 +1,5 @@ +{ + "type": "shared-common", + "id": "@kbn/ml-ui-actions", + "owner": "@elastic/ml-ui" +} diff --git a/x-pack/packages/ml/ui_actions/package.json b/x-pack/packages/ml/ui_actions/package.json new file mode 100644 index 000000000000..a3d77f4701c6 --- /dev/null +++ b/x-pack/packages/ml/ui_actions/package.json @@ -0,0 +1,6 @@ +{ + "name": "@kbn/ml-ui-actions", + "private": true, + "version": "1.0.0", + "license": "Elastic License 2.0" +} \ No newline at end of file diff --git a/x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts b/x-pack/packages/ml/ui_actions/src/aiops/ui_actions.ts new file mode 100644 index 000000000000..b5e9ca07031b --- /dev/null +++ b/x-pack/packages/ml/ui_actions/src/aiops/ui_actions.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import { i18n } from '@kbn/i18n'; +import type { Trigger } from '@kbn/ui-actions-plugin/public'; + +export interface CategorizeFieldContext { + field: DataViewField; + dataView: DataView; + originatingApp: string; + additionalFilter?: { + from: number; + to: number; + field?: { name: string; value: string }; + }; +} + +export const ACTION_CATEGORIZE_FIELD = 'ACTION_CATEGORIZE_FIELD'; + +export const CATEGORIZE_FIELD_TRIGGER = 'CATEGORIZE_FIELD_TRIGGER'; +export const categorizeFieldTrigger: Trigger = { + id: CATEGORIZE_FIELD_TRIGGER, + title: i18n.translate('xpack.ml.actions.runPatternAnalysis.title', { + defaultMessage: 'Run pattern analysis', + }), + description: i18n.translate('xpack.ml.actions.runPatternAnalysis.description', { + defaultMessage: 'Triggered when user wants to run pattern analysis on a field.', + }), +}; diff --git a/x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts b/x-pack/packages/ml/ui_actions/src/ml/ui_actions.ts new file mode 100644 index 000000000000..cf36e3ff01ce --- /dev/null +++ b/x-pack/packages/ml/ui_actions/src/ml/ui_actions.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 type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import type { TimeRange } from '@kbn/es-query'; + +export interface CreateCategorizationADJobContext { + field: DataViewField; + dataView: DataView; + query: QueryDslQueryContainer; + timeRange: TimeRange; +} + +export const CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION = 'createMLADCategorizationJobAction'; + +export const CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER = + 'CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER'; diff --git a/x-pack/packages/ml/ui_actions/tsconfig.json b/x-pack/packages/ml/ui_actions/tsconfig.json new file mode 100644 index 000000000000..ca3f66082b5c --- /dev/null +++ b/x-pack/packages/ml/ui_actions/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "outDir": "target/types", + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ], + "exclude": [ + "target/**/*" + ], + "kbn_references": [ + "@kbn/data-views-plugin", + "@kbn/es-query", + "@kbn/ui-actions-plugin", + "@kbn/i18n", + ] +} diff --git a/x-pack/packages/observability/alerting_test_data/src/create_custom_threshold_rule.ts b/x-pack/packages/observability/alerting_test_data/src/create_custom_threshold_rule.ts index 9c7e1fb6acdb..7ad732af3694 100644 --- a/x-pack/packages/observability/alerting_test_data/src/create_custom_threshold_rule.ts +++ b/x-pack/packages/observability/alerting_test_data/src/create_custom_threshold_rule.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -39,7 +38,6 @@ export const createCustomThresholdRule = async ( params: { criteria: ruleParams.params?.criteria || [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [1], timeSize: 1, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count.ts index c2515cfe1615..be2f2e344d7a 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario1 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.LT, threshold: [100], timeSize: 1, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_groupby.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_groupby.ts index 68786ea4a06d..fe8e2cfa01d3 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_groupby.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_groupby.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario2 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.LT, threshold: [40], timeSize: 1, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_nodata.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_nodata.ts index 97585a66b838..bbb4d4e1c255 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_nodata.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_log_count_nodata.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario3 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.LT, threshold: [5], timeSize: 1, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg.ts index 0feec99ca5a4..dcf6048915eb 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario4 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [80], timeSize: 1, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_groupby.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_groupby.ts index a36bb4af2544..b42006a33a65 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_groupby.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_groupby.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario5 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [80], timeSize: 5, diff --git a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_nodata.ts b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_nodata.ts index 16639c7749ca..9bea0a00eb71 100644 --- a/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_nodata.ts +++ b/x-pack/packages/observability/alerting_test_data/src/scenarios/custom_threshold_metric_avg_nodata.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -23,7 +22,6 @@ export const scenario6 = { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.LT, threshold: [1], timeSize: 1, diff --git a/x-pack/packages/security-solution/data_table/store/data_table/reducer.ts b/x-pack/packages/security-solution/data_table/store/data_table/reducer.ts index f65292a2919e..1ad08a933250 100644 --- a/x-pack/packages/security-solution/data_table/store/data_table/reducer.ts +++ b/x-pack/packages/security-solution/data_table/store/data_table/reducer.ts @@ -95,7 +95,7 @@ export const dataTableReducer = reducerWithInitialState(initialDataTableState) [action.id]: { ...state.tableById[action.id], expandedDetail: { - ...state.tableById[action.id].expandedDetail, + ...state.tableById[action.id]?.expandedDetail, ...updateTableDetailsPanel(action), }, }, diff --git a/x-pack/plugins/actions/docs/openapi/README.md b/x-pack/plugins/actions/docs/openapi/README.md index 2bce08f0b1a4..210bb719eb91 100644 --- a/x-pack/plugins/actions/docs/openapi/README.md +++ b/x-pack/plugins/actions/docs/openapi/README.md @@ -1,6 +1,6 @@ # OpenAPI (Experimental) -The current self-contained spec file is [as JSON](https://raw.githubusercontent.com/elastic/kibana/master/x-pack/plugins/cases/common/openapi/bundled.json) or [as YAML](https://raw.githubusercontent.com/elastic/kibana/master/x-pack/plugins/cases/common/openapi/bundled.yaml) and can be used for online tools like those found at https://openapi.tools/. +The current self-contained spec file is [as JSON](https://raw.githubusercontent.com/elastic/kibana/master/x-pack/plugins/cases/common/openapi/bundled.json) or [as YAML](https://raw.githubusercontent.com/elastic/kibana/master/x-pack/plugins/cases/common/openapi/bundled.yaml) and can be used for online tools like those found at https://openapi.tools/. This spec is experimental and may be incomplete or change later. A guide about the openApi specification can be found at [https://swagger.io/docs/specification/about/](https://swagger.io/docs/specification/about/). diff --git a/x-pack/plugins/actions/docs/openapi/bundled.json b/x-pack/plugins/actions/docs/openapi/bundled.json index 2f8bbf898efe..a2debc66a17a 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.json +++ b/x-pack/plugins/actions/docs/openapi/bundled.json @@ -1,9 +1,9 @@ { - "openapi": "3.0.1", + "openapi": "3.1.0", "info": { "title": "Connectors", "description": "OpenAPI schema for Connectors endpoints", - "version": "0.1", + "version": "0.2", "contact": { "name": "Connectors Team" }, @@ -178,7 +178,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } } ], @@ -303,6 +305,9 @@ "runJiraConnectorRequest": { "$ref": "#/components/examples/run_jira_connector_request" }, + "runPagerDutyConnectorRequest": { + "$ref": "#/components/examples/run_pagerduty_connector_request" + }, "runServerLogConnectorRequest": { "$ref": "#/components/examples/run_server_log_connector_request" }, @@ -368,6 +373,9 @@ "runJiraConnectorResponse": { "$ref": "#/components/examples/run_jira_connector_response" }, + "runPagerDutyConnectorResponse": { + "$ref": "#/components/examples/run_pagerduty_connector_response" + }, "runServerLogConnectorResponse": { "$ref": "#/components/examples/run_server_log_connector_response" }, @@ -451,34 +459,46 @@ "enabled": { "type": "boolean", "description": "Indicates whether the connector type is enabled in Kibana.", - "example": true + "examples": [ + true + ] }, "enabled_in_config": { "type": "boolean", "description": "Indicates whether the connector type is enabled in the Kibana configuration file.", - "example": true + "examples": [ + true + ] }, "enabled_in_license": { "type": "boolean", "description": "Indicates whether the connector is enabled in the license.", - "example": true + "examples": [ + true + ] }, "id": { "$ref": "#/components/schemas/connector_types" }, "is_system_action_type": { "type": "boolean", - "example": false + "examples": [ + false + ] }, "minimum_license_required": { "type": "string", "description": "The license that is required to use the connector type.", - "example": "basic" + "examples": [ + "basic" + ] }, "name": { "type": "string", "description": "The name of the connector type.", - "example": "Index" + "examples": [ + "Index" + ] }, "supported_feature_ids": { "type": "array", @@ -486,10 +506,12 @@ "items": { "$ref": "#/components/schemas/features" }, - "example": [ - "alerting", - "cases", - "siem" + "examples": [ + [ + "alerting", + "cases", + "siem" + ] ] } } @@ -671,7 +693,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } } ], @@ -841,17 +865,23 @@ "enabled": { "type": "boolean", "description": "Indicates whether the connector type is enabled in Kibana.", - "example": true + "examples": [ + true + ] }, "enabled_in_config": { "type": "boolean", "description": "Indicates whether the connector type is enabled in the Kibana `.yml` file.", - "example": true + "examples": [ + true + ] }, "enabled_in_license": { "type": "boolean", "description": "Indicates whether the connector is enabled in the license.", - "example": true + "examples": [ + true + ] }, "id": { "$ref": "#/components/schemas/connector_types" @@ -859,12 +889,16 @@ "minimum_license_required": { "type": "string", "description": "The license that is required to use the connector type.", - "example": "basic" + "examples": [ + "basic" + ] }, "name": { "type": "string", "description": "The name of the connector type.", - "example": "Index" + "examples": [ + "Index" + ] }, "supported_feature_ids": { "type": "array", @@ -872,10 +906,12 @@ "items": { "$ref": "#/components/schemas/features" }, - "example": [ - "alerting", - "uptime", - "siem" + "examples": [ + [ + "alerting", + "uptime", + "siem" + ] ] } } @@ -1243,7 +1279,9 @@ "enabledInLicense": { "type": "boolean", "description": "Indicates whether the connector is enabled in the license.", - "example": true + "examples": [ + true + ] }, "id": { "type": "string", @@ -1362,7 +1400,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "parameters": { @@ -1382,7 +1421,9 @@ "required": true, "schema": { "type": "string", - "example": "df770e30-8b8b-11ed-a780-3b746c987a81" + "examples": [ + "df770e30-8b8b-11ed-a780-3b746c987a81" + ] } }, "space_id": { @@ -1392,7 +1433,9 @@ "required": true, "schema": { "type": "string", - "example": "default" + "examples": [ + "default" + ] } }, "action_id": { @@ -1402,7 +1445,9 @@ "required": true, "schema": { "type": "string", - "example": "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad" + "examples": [ + "c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad" + ] } } }, @@ -1465,12 +1510,16 @@ "enum": [ ".bedrock" ], - "example": ".bedrock" + "examples": [ + ".bedrock" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_bedrock" @@ -1495,11 +1544,13 @@ "createCommentJson": { "type": "string", "description": "A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", - "example": { - "body": { - "[object Object]": null + "examples": [ + { + "body": { + "[object Object]": null + } } - } + ] }, "createCommentMethod": { "type": "string", @@ -1514,24 +1565,28 @@ "createCommentUrl": { "type": "string", "description": "The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + ] }, "createIncidentJson": { "type": "string", "description": "A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", - "example": { - "fields": { - "summary": { - "[object Object]": null - }, - "description": { - "[object Object]": null - }, - "labels": { - "[object Object]": null + "examples": [ + { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } } } - } + ] }, "createIncidentMethod": { "type": "string", @@ -1558,7 +1613,9 @@ "getIncidentUrl": { "type": "string", "description": "The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + ] }, "hasAuth": { "type": "boolean", @@ -1572,19 +1629,21 @@ "updateIncidentJson": { "type": "string", "description": "The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", - "example": { - "fields": { - "summary": { - "[object Object]": null - }, - "description": { - "[object Object]": null - }, - "labels": { - "[object Object]": null + "examples": [ + { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } } } - } + ] }, "updateIncidentMethod": { "type": "string", @@ -1599,12 +1658,16 @@ "updateIncidentUrl": { "type": "string", "description": "The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + ] }, "viewIncidentUrl": { "type": "string", "description": "The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL.\n", - "example": "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + "examples": [ + "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + ] } } }, @@ -1641,12 +1704,16 @@ "enum": [ ".cases-webhook" ], - "example": ".cases-webhook" + "examples": [ + ".cases-webhook" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_cases_webhook" @@ -1701,12 +1768,16 @@ "enum": [ ".d3security" ], - "example": ".d3security" + "examples": [ + ".d3security" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_d3security" @@ -1723,8 +1794,10 @@ "properties": { "clientId": { "description": "The client identifier, which is a part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "from": { "description": "The from address for all emails sent by the connector. It must be specified in `user@host-name` format.\n", @@ -1740,8 +1813,10 @@ "type": "string" }, "oauthTokenUrl": { - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "port": { "description": "The port to connect to on the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. \n", @@ -1765,8 +1840,10 @@ }, "tenantId": { "description": "The tenant identifier, which is part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -1809,12 +1886,16 @@ "enum": [ ".email" ], - "example": ".email" + "examples": [ + ".email" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_email" @@ -1905,12 +1986,16 @@ "enum": [ ".gen-ai" ], - "example": ".gen-ai" + "examples": [ + ".gen-ai" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_genai" @@ -1928,8 +2013,10 @@ "executionTimeField": { "description": "A field that indicates when the document was indexed.", "default": null, - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "index": { "description": "The Elasticsearch index to be written to.", @@ -1961,12 +2048,16 @@ "enum": [ ".index" ], - "example": ".index" + "examples": [ + ".index" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] } } }, @@ -2028,12 +2119,16 @@ "enum": [ ".jira" ], - "example": ".jira" + "examples": [ + ".jira" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_jira" @@ -2088,12 +2183,16 @@ "enum": [ ".opsgenie" ], - "example": ".opsgenie" + "examples": [ + ".opsgenie" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_opsgenie" @@ -2107,9 +2206,13 @@ "properties": { "apiUrl": { "description": "The PagerDuty event URL.", - "type": "string", - "nullable": true, - "example": "https://events.pagerduty.com/v2/enqueue" + "type": [ + "string", + "null" + ], + "examples": [ + "https://events.pagerduty.com/v2/enqueue" + ] } } }, @@ -2147,12 +2250,16 @@ "enum": [ ".pagerduty" ], - "example": ".pagerduty" + "examples": [ + ".pagerduty" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_pagerduty" @@ -2214,7 +2321,9 @@ "connector_type_id": { "description": "The type of connector.", "type": "string", - "example": ".resilient", + "examples": [ + ".resilient" + ], "enum": [ ".resilient" ] @@ -2222,7 +2331,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_resilient" @@ -2244,12 +2355,16 @@ "enum": [ ".server-log" ], - "example": ".server-log" + "examples": [ + ".server-log" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] } } }, @@ -2336,12 +2451,16 @@ "enum": [ ".servicenow" ], - "example": ".servicenow" + "examples": [ + ".servicenow" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -2399,12 +2518,16 @@ "enum": [ ".servicenow-itom" ], - "example": ".servicenow-itom" + "examples": [ + ".servicenow-itom" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -2431,12 +2554,16 @@ "enum": [ ".servicenow-sir" ], - "example": ".servicenow-sir" + "examples": [ + ".servicenow-sir" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -2473,12 +2600,16 @@ "enum": [ ".slack_api" ], - "example": ".slack_api" + "examples": [ + ".slack_api" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_slack_api" @@ -2515,12 +2646,16 @@ "enum": [ ".slack" ], - "example": ".slack" + "examples": [ + ".slack" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_slack_webhook" @@ -2797,12 +2932,16 @@ "enum": [ ".swimlane" ], - "example": ".swimlane" + "examples": [ + ".swimlane" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_swimlane" @@ -2839,12 +2978,16 @@ "enum": [ ".teams" ], - "example": ".teams" + "examples": [ + ".teams" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_teams" @@ -2904,12 +3047,16 @@ "enum": [ ".tines" ], - "example": ".tines" + "examples": [ + ".tines" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_tines" @@ -2964,12 +3111,16 @@ "enum": [ ".torq" ], - "example": ".torq" + "examples": [ + ".torq" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_torq" @@ -3007,8 +3158,10 @@ "description": "If `true`, a user name and password must be provided for login type authentication.\n" }, "headers": { - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "description": "A set of key-value pairs sent as headers with the request." }, "method": { @@ -3083,12 +3236,16 @@ "enum": [ ".webhook" ], - "example": ".webhook" + "examples": [ + ".webhook" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_webhook" @@ -3102,8 +3259,10 @@ "properties": { "configUrl": { "description": "The request URL for the Elastic Alerts trigger in xMatters. It is applicable only when `usesBasic` is `true`.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "usesBasic": { "description": "Specifies whether the connector uses HTTP basic authentication (`true`) or URL authentication (`false`).", @@ -3151,12 +3310,16 @@ "enum": [ ".xmatters" ], - "example": ".xmatters" + "examples": [ + ".xmatters" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_xmatters" @@ -3241,22 +3404,30 @@ "is_deprecated": { "type": "boolean", "description": "Indicates whether the connector type is deprecated.", - "example": false + "examples": [ + false + ] }, "is_missing_secrets": { "type": "boolean", "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", - "example": false + "examples": [ + false + ] }, "is_preconfigured": { "type": "boolean", "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. \n", - "example": false + "examples": [ + false + ] }, "is_system_action": { "type": "boolean", "description": "Indicates whether the connector is used for system actions.", - "example": false + "examples": [ + false + ] }, "connector_response_properties_bedrock": { "title": "Connector response properties for an Amazon Bedrock connector", @@ -3305,7 +3476,9 @@ "referenced_by_count": { "type": "integer", "description": "Indicates the number of saved objects that reference the connector. If `is_preconfigured` is true, this value is not calculated. This property is returned only by the get all connectors API.\n", - "example": 2 + "examples": [ + 2 + ] }, "connector_response_properties_cases_webhook": { "title": "Connector request properties for a Webhook - Case Management connector", @@ -3687,8 +3860,10 @@ ], "properties": { "config": { - "type": "object", - "nullable": true + "type": [ + "object", + "null" + ] }, "connector_type_id": { "type": "string", @@ -4328,7 +4503,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_cases_webhook" @@ -4581,7 +4758,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_swimlane" @@ -4758,6 +4937,30 @@ } ] }, + "run_connector_params_acknowledge_resolve_pagerduty": { + "title": "PagerDuty connector parameters", + "description": "Test an action that acknowledges or resolves a PagerDuty alert.", + "type": "object", + "required": [ + "dedupKey", + "eventAction" + ], + "properties": { + "dedupKey": { + "description": "The deduplication key for the PagerDuty alert.", + "type": "string", + "maxLength": 255 + }, + "eventAction": { + "description": "The type of event.", + "type": "string", + "enum": [ + "acknowledge", + "resolve" + ] + } + } + }, "run_connector_params_documents": { "title": "Index connector parameters", "description": "Test an action that indexes a document into Elasticsearch.", @@ -4862,6 +5065,95 @@ } } }, + "run_connector_params_trigger_pagerduty": { + "title": "PagerDuty connector parameters", + "description": "Test an action that triggers a PagerDuty alert.", + "type": "object", + "required": [ + "eventAction" + ], + "properties": { + "class": { + "description": "The class or type of the event.", + "type": "string", + "examples": [ + "cpu load" + ] + }, + "component": { + "description": "The component of the source machine that is responsible for the event.", + "type": "string", + "examples": [ + "eth0" + ] + }, + "customDetails": { + "description": "Additional details to add to the event.", + "type": "object" + }, + "dedupKey": { + "description": "All actions sharing this key will be associated with the same PagerDuty alert. This value is used to correlate trigger and resolution.\n", + "type": "string", + "maxLength": 255 + }, + "eventAction": { + "description": "The type of event.", + "type": "string", + "enum": [ + "trigger" + ] + }, + "group": { + "description": "The logical grouping of components of a service.", + "type": "string", + "examples": [ + "app-stack" + ] + }, + "links": { + "description": "A list of links to add to the event.", + "type": "array", + "items": { + "type": "object", + "properties": { + "href": { + "description": "The URL for the link.", + "type": "string" + }, + "text": { + "description": "A plain text description of the purpose of the link.", + "type": "string" + } + } + } + }, + "severity": { + "description": "The severity of the event on the affected system.", + "type": "string", + "enum": [ + "critical", + "error", + "info", + "warning" + ], + "default": "info" + }, + "source": { + "description": "The affected system, such as a hostname or fully qualified domain name. Defaults to the Kibana saved object id of the action.\n", + "type": "string" + }, + "summary": { + "description": "A summery of the event.", + "type": "string", + "maxLength": 1024 + }, + "timestamp": { + "description": "An ISO-8601 timestamp that indicates when the event was detected or generated.", + "type": "string", + "format": "date-time" + } + } + }, "run_connector_subaction_addevent": { "title": "The addEvent subaction", "type": "object", @@ -5012,10 +5304,12 @@ "type": "object", "description": "The custom properties of the alert.", "additionalProperties": true, - "example": { - "key1": "value1", - "key2": "value2" - } + "examples": [ + { + "key1": "value1", + "key2": "value2" + } + ] }, "entity": { "type": "string", @@ -5147,7 +5441,9 @@ "id": { "type": "string", "description": "The Jira issue type identifier.", - "example": 10024 + "examples": [ + 10024 + ] } } } @@ -5229,7 +5525,9 @@ "externalId": { "type": "string", "description": "The Jira, ServiceNow ITSM, or ServiceNow SecOps issue identifier.", - "example": 71778 + "examples": [ + 71778 + ] } } } @@ -5259,7 +5557,9 @@ "id": { "type": "string", "description": "The Jira issue identifier.", - "example": 71778 + "examples": [ + 71778 + ] } } } @@ -5509,6 +5809,9 @@ "properties": { "params": { "oneOf": [ + { + "$ref": "#/components/schemas/run_connector_params_acknowledge_resolve_pagerduty" + }, { "$ref": "#/components/schemas/run_connector_params_documents" }, @@ -5518,6 +5821,9 @@ { "$ref": "#/components/schemas/run_connector_params_message_serverlog" }, + { + "$ref": "#/components/schemas/run_connector_params_trigger_pagerduty" + }, { "title": "Subaction parameters", "description": "Test an action that involves a subaction.", @@ -5603,7 +5909,9 @@ ".webhook", ".xmatters" ], - "example": ".server-log" + "examples": [ + ".server-log" + ] }, "action_response_properties": { "title": "Action response properties", @@ -5838,6 +6146,24 @@ } } }, + "run_pagerduty_connector_request": { + "summary": "Run a PagerDuty connector to trigger an alert.", + "value": { + "params": { + "eventAction": "trigger", + "summary": "A brief event summary", + "links": [ + { + "href": "http://example.com/pagerduty", + "text": "An example link" + } + ], + "customDetails": { + "my_data_1": "test data" + } + } + } + }, "run_server_log_connector_request": { "summary": "Run a server log connector.", "value": { @@ -5974,6 +6300,18 @@ "status": "ok" } }, + "run_pagerduty_connector_response": { + "summary": "Response from running a PagerDuty connector.", + "value": { + "connector_id": "45de9f70-954f-4608-b12a-db7cf808e49d", + "data": { + "dedup_key": "5115e138b26b484a81eaea779faa6016", + "message": "Event processed", + "status": "success" + }, + "status": "ok" + } + }, "run_server_log_connector_response": { "summary": "Response from running a server log connector.", "value": { @@ -6176,7 +6514,9 @@ "properties": { "error": { "type": "string", - "example": "Unauthorized", + "examples": [ + "Unauthorized" + ], "enum": [ "Unauthorized" ] @@ -6186,7 +6526,9 @@ }, "statusCode": { "type": "integer", - "example": 401, + "examples": [ + 401 + ], "enum": [ 401 ] @@ -6206,18 +6548,24 @@ "properties": { "error": { "type": "string", - "example": "Not Found", + "examples": [ + "Not Found" + ], "enum": [ "Not Found" ] }, "message": { "type": "string", - "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + "examples": [ + "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + ] }, "statusCode": { "type": "integer", - "example": 404, + "examples": [ + 404 + ], "enum": [ 404 ] diff --git a/x-pack/plugins/actions/docs/openapi/bundled.yaml b/x-pack/plugins/actions/docs/openapi/bundled.yaml index 481d0f0a7ec4..50856a35f939 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Connectors description: OpenAPI schema for Connectors endpoints - version: '0.1' + version: '0.2' contact: name: Connectors Team license: @@ -109,7 +109,8 @@ paths: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: @@ -185,6 +186,8 @@ paths: $ref: '#/components/examples/run_index_connector_request' runJiraConnectorRequest: $ref: '#/components/examples/run_jira_connector_request' + runPagerDutyConnectorRequest: + $ref: '#/components/examples/run_pagerduty_connector_request' runServerLogConnectorRequest: $ref: '#/components/examples/run_server_log_connector_request' runServiceNowITOMConnectorRequest: @@ -227,6 +230,8 @@ paths: $ref: '#/components/examples/run_index_connector_response' runJiraConnectorResponse: $ref: '#/components/examples/run_jira_connector_response' + runPagerDutyConnectorResponse: + $ref: '#/components/examples/run_pagerduty_connector_response' runServerLogConnectorResponse: $ref: '#/components/examples/run_server_log_connector_response' runServiceNowITOMConnectorResponse: @@ -282,37 +287,43 @@ paths: enabled: type: boolean description: Indicates whether the connector type is enabled in Kibana. - example: true + examples: + - true enabled_in_config: type: boolean description: Indicates whether the connector type is enabled in the Kibana configuration file. - example: true + examples: + - true enabled_in_license: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: $ref: '#/components/schemas/connector_types' is_system_action_type: type: boolean - example: false + examples: + - false minimum_license_required: type: string description: The license that is required to use the connector type. - example: basic + examples: + - basic name: type: string description: The name of the connector type. - example: Index + examples: + - Index supported_feature_ids: type: array description: The features that are supported by the connector type. items: $ref: '#/components/schemas/features' - example: - - alerting - - cases - - siem + examples: + - - alerting + - cases + - siem examples: getConnectorTypesServerlessResponse: $ref: '#/components/examples/get_connector_types_generativeai_response' @@ -421,7 +432,8 @@ paths: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: @@ -530,34 +542,39 @@ paths: enabled: type: boolean description: Indicates whether the connector type is enabled in Kibana. - example: true + examples: + - true enabled_in_config: type: boolean description: Indicates whether the connector type is enabled in the Kibana `.yml` file. - example: true + examples: + - true enabled_in_license: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: $ref: '#/components/schemas/connector_types' minimum_license_required: type: string description: The license that is required to use the connector type. - example: basic + examples: + - basic name: type: string description: The name of the connector type. - example: Index + examples: + - Index supported_feature_ids: type: array description: The Kibana features that are supported by the connector type. items: $ref: '#/components/schemas/features' - example: - - alerting - - uptime - - siem + examples: + - - alerting + - uptime + - siem examples: getConnectorTypesResponse: $ref: '#/components/examples/get_connector_types_response' @@ -789,7 +806,8 @@ paths: enabledInLicense: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: type: string description: The unique identifier for the connector type. @@ -859,7 +877,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' parameters: kbn_xsrf: schema: @@ -875,7 +894,8 @@ components: required: true schema: type: string - example: df770e30-8b8b-11ed-a780-3b746c987a81 + examples: + - df770e30-8b8b-11ed-a780-3b746c987a81 space_id: in: path name: spaceId @@ -883,7 +903,8 @@ components: required: true schema: type: string - example: default + examples: + - default action_id: in: path name: actionId @@ -891,7 +912,8 @@ components: required: true schema: type: string - example: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + examples: + - c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad schemas: config_properties_bedrock: title: Connector request properties for an Amazon Bedrock connector @@ -939,11 +961,13 @@ components: description: The type of connector. enum: - .bedrock - example: .bedrock + examples: + - .bedrock name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_bedrock' config_properties_cases_webhook: @@ -964,9 +988,9 @@ components: type: string description: | A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: - body: - '[object Object]': null + examples: + - body: + '[object Object]': null createCommentMethod: type: string description: | @@ -980,19 +1004,20 @@ components: type: string description: | The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment createIncidentJson: type: string description: | A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: - fields: - summary: - '[object Object]': null - description: - '[object Object]': null - labels: - '[object Object]': null + examples: + - fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null createIncidentMethod: type: string description: | @@ -1016,7 +1041,8 @@ components: type: string description: | The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} hasAuth: type: boolean description: If true, a username and password for login type authentication must be provided. @@ -1029,14 +1055,14 @@ components: type: string description: | The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: - fields: - summary: - '[object Object]': null - description: - '[object Object]': null - labels: - '[object Object]': null + examples: + - fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null updateIncidentMethod: type: string description: | @@ -1050,12 +1076,14 @@ components: type: string description: | The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} viewIncidentUrl: type: string description: | The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL. - example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + examples: + - https://testing-jira.atlassian.net/browse/{{{external.system.title}}} secrets_properties_cases_webhook: title: Connector secrets properties for Webhook - Case Management connector type: object @@ -1083,11 +1111,13 @@ components: description: The type of connector. enum: - .cases-webhook - example: .cases-webhook + examples: + - .cases-webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_cases_webhook' config_properties_d3security: @@ -1129,11 +1159,13 @@ components: description: The type of connector. enum: - .d3security - example: .d3security + examples: + - .d3security name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_d3security' config_properties_email: @@ -1146,8 +1178,9 @@ components: clientId: description: | The client identifier, which is a part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true + type: + - string + - 'null' from: description: | The from address for all emails sent by the connector. It must be specified in `user@host-name` format. @@ -1162,8 +1195,9 @@ components: The host name of the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. type: string oauthTokenUrl: - type: string - nullable: true + type: + - string + - 'null' port: description: | The port to connect to on the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. @@ -1186,8 +1220,9 @@ components: tenantId: description: | The tenant identifier, which is part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true + type: + - string + - 'null' secrets_properties_email: title: Connector secrets properties for an email connector description: Defines secrets for connectors when type is `.email`. @@ -1223,11 +1258,13 @@ components: description: The type of connector. enum: - .email - example: .email + examples: + - .email name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_email' config_properties_genai: @@ -1291,11 +1328,13 @@ components: description: The type of connector. enum: - .gen-ai - example: .gen-ai + examples: + - .gen-ai name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_genai' config_properties_index: @@ -1308,8 +1347,9 @@ components: executionTimeField: description: A field that indicates when the document was indexed. default: null - type: string - nullable: true + type: + - string + - 'null' index: description: The Elasticsearch index to be written to. type: string @@ -1334,11 +1374,13 @@ components: description: The type of connector. enum: - .index - example: .index + examples: + - .index name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector config_properties_jira: title: Connector request properties for a Jira connector required: @@ -1384,11 +1426,13 @@ components: description: The type of connector. enum: - .jira - example: .jira + examples: + - .jira name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_jira' config_properties_opsgenie: @@ -1429,11 +1473,13 @@ components: description: The type of connector. enum: - .opsgenie - example: .opsgenie + examples: + - .opsgenie name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_opsgenie' config_properties_pagerduty: @@ -1443,9 +1489,11 @@ components: properties: apiUrl: description: The PagerDuty event URL. - type: string - nullable: true - example: https://events.pagerduty.com/v2/enqueue + type: + - string + - 'null' + examples: + - https://events.pagerduty.com/v2/enqueue secrets_properties_pagerduty: title: Connector secrets properties for a PagerDuty connector description: Defines secrets for connectors when type is `.pagerduty`. @@ -1475,11 +1523,13 @@ components: description: The type of connector. enum: - .pagerduty - example: .pagerduty + examples: + - .pagerduty name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_pagerduty' config_properties_resilient: @@ -1525,13 +1575,15 @@ components: connector_type_id: description: The type of connector. type: string - example: .resilient + examples: + - .resilient enum: - .resilient name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_resilient' create_connector_request_serverlog: @@ -1547,11 +1599,13 @@ components: description: The type of connector. enum: - .server-log - example: .server-log + examples: + - .server-log name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector config_properties_servicenow: title: Connector request properties for a ServiceNow ITSM connector required: @@ -1622,11 +1676,13 @@ components: description: The type of connector. enum: - .servicenow - example: .servicenow + examples: + - .servicenow name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' config_properties_servicenow_itom: @@ -1674,11 +1730,13 @@ components: description: The type of connector. enum: - .servicenow-itom - example: .servicenow-itom + examples: + - .servicenow-itom name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' create_connector_request_servicenow_sir: @@ -1699,11 +1757,13 @@ components: description: The type of connector. enum: - .servicenow-sir - example: .servicenow-sir + examples: + - .servicenow-sir name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' secrets_properties_slack_api: @@ -1730,11 +1790,13 @@ components: description: The type of connector. enum: - .slack_api - example: .slack_api + examples: + - .slack_api name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_slack_api' secrets_properties_slack_webhook: @@ -1761,11 +1823,13 @@ components: description: The type of connector. enum: - .slack - example: .slack + examples: + - .slack name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_slack_webhook' config_properties_swimlane: @@ -1974,11 +2038,13 @@ components: description: The type of connector. enum: - .swimlane - example: .swimlane + examples: + - .swimlane name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_swimlane' secrets_properties_teams: @@ -2006,11 +2072,13 @@ components: description: The type of connector. enum: - .teams - example: .teams + examples: + - .teams name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_teams' config_properties_tines: @@ -2056,11 +2124,13 @@ components: description: The type of connector. enum: - .tines - example: .tines + examples: + - .tines name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_tines' config_properties_torq: @@ -2101,11 +2171,13 @@ components: description: The type of connector. enum: - .torq - example: .torq + examples: + - .torq name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_torq' config_properties_webhook: @@ -2137,8 +2209,9 @@ components: description: | If `true`, a user name and password must be provided for login type authentication. headers: - type: object - nullable: true + type: + - object + - 'null' description: A set of key-value pairs sent as headers with the request. method: type: string @@ -2201,11 +2274,13 @@ components: description: The type of connector. enum: - .webhook - example: .webhook + examples: + - .webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_webhook' config_properties_xmatters: @@ -2216,8 +2291,9 @@ components: configUrl: description: | The request URL for the Elastic Alerts trigger in xMatters. It is applicable only when `usesBasic` is `true`. - type: string - nullable: true + type: + - string + - 'null' usesBasic: description: Specifies whether the connector uses HTTP basic authentication (`true`) or URL authentication (`false`). type: boolean @@ -2257,11 +2333,13 @@ components: description: The type of connector. enum: - .xmatters - example: .xmatters + examples: + - .xmatters name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_xmatters' create_connector_request: @@ -2295,20 +2373,24 @@ components: is_deprecated: type: boolean description: Indicates whether the connector type is deprecated. - example: false + examples: + - false is_missing_secrets: type: boolean description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. - example: false + examples: + - false is_preconfigured: type: boolean description: | Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. - example: false + examples: + - false is_system_action: type: boolean description: Indicates whether the connector is used for system actions. - example: false + examples: + - false connector_response_properties_bedrock: title: Connector response properties for an Amazon Bedrock connector type: object @@ -2345,7 +2427,8 @@ components: type: integer description: | Indicates the number of saved objects that reference the connector. If `is_preconfigured` is true, this value is not calculated. This property is returned only by the get all connectors API. - example: 2 + examples: + - 2 connector_response_properties_cases_webhook: title: Connector request properties for a Webhook - Case Management connector type: object @@ -2621,8 +2704,9 @@ components: - name properties: config: - type: object - nullable: true + type: + - object + - 'null' connector_type_id: type: string description: The type of connector. @@ -3056,7 +3140,8 @@ components: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_cases_webhook' update_connector_request_d3security: @@ -3236,7 +3321,8 @@ components: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_swimlane' update_connector_request_teams: @@ -3336,6 +3422,24 @@ components: - $ref: '#/components/schemas/update_connector_request_torq' - $ref: '#/components/schemas/update_connector_request_webhook' - $ref: '#/components/schemas/update_connector_request_xmatters' + run_connector_params_acknowledge_resolve_pagerduty: + title: PagerDuty connector parameters + description: Test an action that acknowledges or resolves a PagerDuty alert. + type: object + required: + - dedupKey + - eventAction + properties: + dedupKey: + description: The deduplication key for the PagerDuty alert. + type: string + maxLength: 255 + eventAction: + description: The type of event. + type: string + enum: + - acknowledge + - resolve run_connector_params_documents: title: Index connector parameters description: Test an action that indexes a document into Elasticsearch. @@ -3413,6 +3517,74 @@ components: message: type: string description: The message for server log connectors. + run_connector_params_trigger_pagerduty: + title: PagerDuty connector parameters + description: Test an action that triggers a PagerDuty alert. + type: object + required: + - eventAction + properties: + class: + description: The class or type of the event. + type: string + examples: + - cpu load + component: + description: The component of the source machine that is responsible for the event. + type: string + examples: + - eth0 + customDetails: + description: Additional details to add to the event. + type: object + dedupKey: + description: | + All actions sharing this key will be associated with the same PagerDuty alert. This value is used to correlate trigger and resolution. + type: string + maxLength: 255 + eventAction: + description: The type of event. + type: string + enum: + - trigger + group: + description: The logical grouping of components of a service. + type: string + examples: + - app-stack + links: + description: A list of links to add to the event. + type: array + items: + type: object + properties: + href: + description: The URL for the link. + type: string + text: + description: A plain text description of the purpose of the link. + type: string + severity: + description: The severity of the event on the affected system. + type: string + enum: + - critical + - error + - info + - warning + default: info + source: + description: | + The affected system, such as a hostname or fully qualified domain name. Defaults to the Kibana saved object id of the action. + type: string + summary: + description: A summery of the event. + type: string + maxLength: 1024 + timestamp: + description: An ISO-8601 timestamp that indicates when the event was detected or generated. + type: string + format: date-time run_connector_subaction_addevent: title: The addEvent subaction type: object @@ -3525,9 +3697,9 @@ components: type: object description: The custom properties of the alert. additionalProperties: true - example: - key1: value1 - key2: value2 + examples: + - key1: value1 + key2: value2 entity: type: string description: The domain of the alert. For example, the application or server name. @@ -3625,7 +3797,8 @@ components: id: type: string description: The Jira issue type identifier. - example: 10024 + examples: + - 10024 run_connector_subaction_getchoices: title: The getChoices subaction type: object @@ -3683,7 +3856,8 @@ components: externalId: type: string description: The Jira, ServiceNow ITSM, or ServiceNow SecOps issue identifier. - example: 71778 + examples: + - 71778 run_connector_subaction_issue: title: The issue subaction type: object @@ -3704,7 +3878,8 @@ components: id: type: string description: The Jira issue identifier. - example: 71778 + examples: + - 71778 run_connector_subaction_issues: title: The issues subaction type: object @@ -3877,9 +4052,11 @@ components: properties: params: oneOf: + - $ref: '#/components/schemas/run_connector_params_acknowledge_resolve_pagerduty' - $ref: '#/components/schemas/run_connector_params_documents' - $ref: '#/components/schemas/run_connector_params_message_email' - $ref: '#/components/schemas/run_connector_params_message_serverlog' + - $ref: '#/components/schemas/run_connector_params_trigger_pagerduty' - title: Subaction parameters description: Test an action that involves a subaction. oneOf: @@ -3933,7 +4110,8 @@ components: - .torq - .webhook - .xmatters - example: .server-log + examples: + - .server-log action_response_properties: title: Action response properties description: The properties vary depending on the action type. @@ -4110,6 +4288,17 @@ components: value: params: subAction: issueTypes + run_pagerduty_connector_request: + summary: Run a PagerDuty connector to trigger an alert. + value: + params: + eventAction: trigger + summary: A brief event summary + links: + - href: http://example.com/pagerduty + text: An example link + customDetails: + my_data_1: test data run_server_log_connector_request: summary: Run a server log connector. value: @@ -4201,6 +4390,15 @@ components: - id: 10000 name: Epic status: ok + run_pagerduty_connector_response: + summary: Response from running a PagerDuty connector. + value: + connector_id: 45de9f70-954f-4608-b12a-db7cf808e49d + data: + dedup_key: 5115e138b26b484a81eaea779faa6016 + message: Event processed + status: success + status: ok run_server_log_connector_response: summary: Response from running a server log connector. value: @@ -4347,14 +4545,16 @@ components: properties: error: type: string - example: Unauthorized + examples: + - Unauthorized enum: - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 enum: - 401 '404': @@ -4367,15 +4567,18 @@ components: properties: error: type: string - example: Not Found + examples: + - Not Found enum: - Not Found message: type: string - example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + examples: + - Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found statusCode: type: integer - example: 404 + examples: + - 404 enum: - 404 200_actions: diff --git a/x-pack/plugins/actions/docs/openapi/bundled_serverless.json b/x-pack/plugins/actions/docs/openapi/bundled_serverless.json index dadcc4cc0876..769fdf2d258e 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled_serverless.json +++ b/x-pack/plugins/actions/docs/openapi/bundled_serverless.json @@ -1,9 +1,9 @@ { - "openapi": "3.0.1", + "openapi": "3.1.0", "info": { "title": "Connectors", "description": "OpenAPI schema for connectors in Serverless projects", - "version": "0.1", + "version": "0.2", "contact": { "name": "Connectors Team" }, @@ -180,7 +180,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } } ], @@ -336,34 +338,46 @@ "enabled": { "type": "boolean", "description": "Indicates whether the connector type is enabled in Kibana.", - "example": true + "examples": [ + true + ] }, "enabled_in_config": { "type": "boolean", "description": "Indicates whether the connector type is enabled in the Kibana configuration file.", - "example": true + "examples": [ + true + ] }, "enabled_in_license": { "type": "boolean", "description": "Indicates whether the connector is enabled in the license.", - "example": true + "examples": [ + true + ] }, "id": { "$ref": "#/components/schemas/connector_types" }, "is_system_action_type": { "type": "boolean", - "example": false + "examples": [ + false + ] }, "minimum_license_required": { "type": "string", "description": "The license that is required to use the connector type.", - "example": "basic" + "examples": [ + "basic" + ] }, "name": { "type": "string", "description": "The name of the connector type.", - "example": "Index" + "examples": [ + "Index" + ] }, "supported_feature_ids": { "type": "array", @@ -371,10 +385,12 @@ "items": { "$ref": "#/components/schemas/features" }, - "example": [ - "alerting", - "cases", - "siem" + "examples": [ + [ + "alerting", + "cases", + "siem" + ] ] } } @@ -400,7 +416,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "parameters": { @@ -420,7 +437,9 @@ "required": true, "schema": { "type": "string", - "example": "df770e30-8b8b-11ed-a780-3b746c987a81" + "examples": [ + "df770e30-8b8b-11ed-a780-3b746c987a81" + ] } } }, @@ -483,12 +502,16 @@ "enum": [ ".bedrock" ], - "example": ".bedrock" + "examples": [ + ".bedrock" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_bedrock" @@ -513,11 +536,13 @@ "createCommentJson": { "type": "string", "description": "A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", - "example": { - "body": { - "[object Object]": null + "examples": [ + { + "body": { + "[object Object]": null + } } - } + ] }, "createCommentMethod": { "type": "string", @@ -532,24 +557,28 @@ "createCommentUrl": { "type": "string", "description": "The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment" + ] }, "createIncidentJson": { "type": "string", "description": "A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", - "example": { - "fields": { - "summary": { - "[object Object]": null - }, - "description": { - "[object Object]": null - }, - "labels": { - "[object Object]": null + "examples": [ + { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } } } - } + ] }, "createIncidentMethod": { "type": "string", @@ -576,7 +605,9 @@ "getIncidentUrl": { "type": "string", "description": "The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}" + ] }, "hasAuth": { "type": "boolean", @@ -590,19 +621,21 @@ "updateIncidentJson": { "type": "string", "description": "The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review.\n", - "example": { - "fields": { - "summary": { - "[object Object]": null - }, - "description": { - "[object Object]": null - }, - "labels": { - "[object Object]": null + "examples": [ + { + "fields": { + "summary": { + "[object Object]": null + }, + "description": { + "[object Object]": null + }, + "labels": { + "[object Object]": null + } } } - } + ] }, "updateIncidentMethod": { "type": "string", @@ -617,12 +650,16 @@ "updateIncidentUrl": { "type": "string", "description": "The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts.\n", - "example": "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + "examples": [ + "https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}}" + ] }, "viewIncidentUrl": { "type": "string", "description": "The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL.\n", - "example": "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + "examples": [ + "https://testing-jira.atlassian.net/browse/{{{external.system.title}}}" + ] } } }, @@ -659,12 +696,16 @@ "enum": [ ".cases-webhook" ], - "example": ".cases-webhook" + "examples": [ + ".cases-webhook" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_cases_webhook" @@ -719,12 +760,16 @@ "enum": [ ".d3security" ], - "example": ".d3security" + "examples": [ + ".d3security" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_d3security" @@ -741,8 +786,10 @@ "properties": { "clientId": { "description": "The client identifier, which is a part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "from": { "description": "The from address for all emails sent by the connector. It must be specified in `user@host-name` format.\n", @@ -758,8 +805,10 @@ "type": "string" }, "oauthTokenUrl": { - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "port": { "description": "The port to connect to on the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. \n", @@ -783,8 +832,10 @@ }, "tenantId": { "description": "The tenant identifier, which is part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -827,12 +878,16 @@ "enum": [ ".email" ], - "example": ".email" + "examples": [ + ".email" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_email" @@ -923,12 +978,16 @@ "enum": [ ".gen-ai" ], - "example": ".gen-ai" + "examples": [ + ".gen-ai" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_genai" @@ -946,8 +1005,10 @@ "executionTimeField": { "description": "A field that indicates when the document was indexed.", "default": null, - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "index": { "description": "The Elasticsearch index to be written to.", @@ -979,12 +1040,16 @@ "enum": [ ".index" ], - "example": ".index" + "examples": [ + ".index" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] } } }, @@ -1046,12 +1111,16 @@ "enum": [ ".jira" ], - "example": ".jira" + "examples": [ + ".jira" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_jira" @@ -1106,12 +1175,16 @@ "enum": [ ".opsgenie" ], - "example": ".opsgenie" + "examples": [ + ".opsgenie" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_opsgenie" @@ -1125,9 +1198,13 @@ "properties": { "apiUrl": { "description": "The PagerDuty event URL.", - "type": "string", - "nullable": true, - "example": "https://events.pagerduty.com/v2/enqueue" + "type": [ + "string", + "null" + ], + "examples": [ + "https://events.pagerduty.com/v2/enqueue" + ] } } }, @@ -1165,12 +1242,16 @@ "enum": [ ".pagerduty" ], - "example": ".pagerduty" + "examples": [ + ".pagerduty" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_pagerduty" @@ -1232,7 +1313,9 @@ "connector_type_id": { "description": "The type of connector.", "type": "string", - "example": ".resilient", + "examples": [ + ".resilient" + ], "enum": [ ".resilient" ] @@ -1240,7 +1323,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_resilient" @@ -1262,12 +1347,16 @@ "enum": [ ".server-log" ], - "example": ".server-log" + "examples": [ + ".server-log" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] } } }, @@ -1354,12 +1443,16 @@ "enum": [ ".servicenow" ], - "example": ".servicenow" + "examples": [ + ".servicenow" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -1417,12 +1510,16 @@ "enum": [ ".servicenow-itom" ], - "example": ".servicenow-itom" + "examples": [ + ".servicenow-itom" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -1449,12 +1546,16 @@ "enum": [ ".servicenow-sir" ], - "example": ".servicenow-sir" + "examples": [ + ".servicenow-sir" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_servicenow" @@ -1491,12 +1592,16 @@ "enum": [ ".slack_api" ], - "example": ".slack_api" + "examples": [ + ".slack_api" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_slack_api" @@ -1533,12 +1638,16 @@ "enum": [ ".slack" ], - "example": ".slack" + "examples": [ + ".slack" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_slack_webhook" @@ -1815,12 +1924,16 @@ "enum": [ ".swimlane" ], - "example": ".swimlane" + "examples": [ + ".swimlane" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_swimlane" @@ -1857,12 +1970,16 @@ "enum": [ ".teams" ], - "example": ".teams" + "examples": [ + ".teams" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_teams" @@ -1922,12 +2039,16 @@ "enum": [ ".tines" ], - "example": ".tines" + "examples": [ + ".tines" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_tines" @@ -1982,12 +2103,16 @@ "enum": [ ".torq" ], - "example": ".torq" + "examples": [ + ".torq" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_torq" @@ -2025,8 +2150,10 @@ "description": "If `true`, a user name and password must be provided for login type authentication.\n" }, "headers": { - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "description": "A set of key-value pairs sent as headers with the request." }, "method": { @@ -2101,12 +2228,16 @@ "enum": [ ".webhook" ], - "example": ".webhook" + "examples": [ + ".webhook" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_webhook" @@ -2120,8 +2251,10 @@ "properties": { "configUrl": { "description": "The request URL for the Elastic Alerts trigger in xMatters. It is applicable only when `usesBasic` is `true`.\n", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "usesBasic": { "description": "Specifies whether the connector uses HTTP basic authentication (`true`) or URL authentication (`false`).", @@ -2169,12 +2302,16 @@ "enum": [ ".xmatters" ], - "example": ".xmatters" + "examples": [ + ".xmatters" + ] }, "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_xmatters" @@ -2259,22 +2396,30 @@ "is_deprecated": { "type": "boolean", "description": "Indicates whether the connector type is deprecated.", - "example": false + "examples": [ + false + ] }, "is_missing_secrets": { "type": "boolean", "description": "Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type.", - "example": false + "examples": [ + false + ] }, "is_preconfigured": { "type": "boolean", "description": "Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. \n", - "example": false + "examples": [ + false + ] }, "is_system_action": { "type": "boolean", "description": "Indicates whether the connector is used for system actions.", - "example": false + "examples": [ + false + ] }, "connector_response_properties_bedrock": { "title": "Connector response properties for an Amazon Bedrock connector", @@ -2323,7 +2468,9 @@ "referenced_by_count": { "type": "integer", "description": "Indicates the number of saved objects that reference the connector. If `is_preconfigured` is true, this value is not calculated. This property is returned only by the get all connectors API.\n", - "example": 2 + "examples": [ + 2 + ] }, "connector_response_properties_cases_webhook": { "title": "Connector request properties for a Webhook - Case Management connector", @@ -2705,8 +2852,10 @@ ], "properties": { "config": { - "type": "object", - "nullable": true + "type": [ + "object", + "null" + ] }, "connector_type_id": { "type": "string", @@ -3346,7 +3495,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_cases_webhook" @@ -3599,7 +3750,9 @@ "name": { "type": "string", "description": "The display name for the connector.", - "example": "my-connector" + "examples": [ + "my-connector" + ] }, "secrets": { "$ref": "#/components/schemas/secrets_properties_swimlane" @@ -3815,7 +3968,9 @@ ".webhook", ".xmatters" ], - "example": ".server-log" + "examples": [ + ".server-log" + ] } }, "examples": { @@ -4048,7 +4203,9 @@ "properties": { "error": { "type": "string", - "example": "Unauthorized", + "examples": [ + "Unauthorized" + ], "enum": [ "Unauthorized" ] @@ -4058,7 +4215,9 @@ }, "statusCode": { "type": "integer", - "example": 401, + "examples": [ + 401 + ], "enum": [ 401 ] @@ -4078,18 +4237,24 @@ "properties": { "error": { "type": "string", - "example": "Not Found", + "examples": [ + "Not Found" + ], "enum": [ "Not Found" ] }, "message": { "type": "string", - "example": "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + "examples": [ + "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + ] }, "statusCode": { "type": "integer", - "example": 404, + "examples": [ + 404 + ], "enum": [ 404 ] diff --git a/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml b/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml index fbe684c35fe4..15a9dfb0be29 100644 --- a/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml +++ b/x-pack/plugins/actions/docs/openapi/bundled_serverless.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Connectors description: OpenAPI schema for connectors in Serverless projects - version: '0.1' + version: '0.2' contact: name: Connectors Team license: @@ -111,7 +111,8 @@ paths: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: @@ -210,37 +211,43 @@ paths: enabled: type: boolean description: Indicates whether the connector type is enabled in Kibana. - example: true + examples: + - true enabled_in_config: type: boolean description: Indicates whether the connector type is enabled in the Kibana configuration file. - example: true + examples: + - true enabled_in_license: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: $ref: '#/components/schemas/connector_types' is_system_action_type: type: boolean - example: false + examples: + - false minimum_license_required: type: string description: The license that is required to use the connector type. - example: basic + examples: + - basic name: type: string description: The name of the connector type. - example: Index + examples: + - Index supported_feature_ids: type: array description: The features that are supported by the connector type. items: $ref: '#/components/schemas/features' - example: - - alerting - - cases - - siem + examples: + - - alerting + - cases + - siem examples: getConnectorTypesServerlessResponse: $ref: '#/components/examples/get_connector_types_generativeai_response' @@ -251,7 +258,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' parameters: kbn_xsrf: schema: @@ -267,7 +275,8 @@ components: required: true schema: type: string - example: df770e30-8b8b-11ed-a780-3b746c987a81 + examples: + - df770e30-8b8b-11ed-a780-3b746c987a81 schemas: config_properties_bedrock: title: Connector request properties for an Amazon Bedrock connector @@ -315,11 +324,13 @@ components: description: The type of connector. enum: - .bedrock - example: .bedrock + examples: + - .bedrock name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_bedrock' config_properties_cases_webhook: @@ -340,9 +351,9 @@ components: type: string description: | A JSON payload sent to the create comment URL to create a case comment. You can use variables to add Kibana Cases data to the payload. The required variable is `case.comment`. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: - body: - '[object Object]': null + examples: + - body: + '[object Object]': null createCommentMethod: type: string description: | @@ -356,19 +367,20 @@ components: type: string description: | The REST API URL to create a case comment by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment createIncidentJson: type: string description: | A JSON payload sent to the create case URL to create a case. You can use variables to add case data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: - fields: - summary: - '[object Object]': null - description: - '[object Object]': null - labels: - '[object Object]': null + examples: + - fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null createIncidentMethod: type: string description: | @@ -392,7 +404,8 @@ components: type: string description: | The REST API URL to get the case by ID from the third-party system. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. You can use a variable to add the external system ID to the URL. Due to Mustache template variables (the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} hasAuth: type: boolean description: If true, a username and password for login type authentication must be provided. @@ -405,14 +418,14 @@ components: type: string description: | The JSON payload sent to the update case URL to update the case. You can use variables to add Kibana Cases data to the payload. Required variables are `case.title` and `case.description`. Due to Mustache template variables (which is the text enclosed in triple braces, for example, `{{{case.title}}}`), the JSON is not validated when you create the connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: - fields: - summary: - '[object Object]': null - description: - '[object Object]': null - labels: - '[object Object]': null + examples: + - fields: + summary: + '[object Object]': null + description: + '[object Object]': null + labels: + '[object Object]': null updateIncidentMethod: type: string description: | @@ -426,12 +439,14 @@ components: type: string description: | The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} viewIncidentUrl: type: string description: | The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL. - example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + examples: + - https://testing-jira.atlassian.net/browse/{{{external.system.title}}} secrets_properties_cases_webhook: title: Connector secrets properties for Webhook - Case Management connector type: object @@ -459,11 +474,13 @@ components: description: The type of connector. enum: - .cases-webhook - example: .cases-webhook + examples: + - .cases-webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_cases_webhook' config_properties_d3security: @@ -505,11 +522,13 @@ components: description: The type of connector. enum: - .d3security - example: .d3security + examples: + - .d3security name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_d3security' config_properties_email: @@ -522,8 +541,9 @@ components: clientId: description: | The client identifier, which is a part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true + type: + - string + - 'null' from: description: | The from address for all emails sent by the connector. It must be specified in `user@host-name` format. @@ -538,8 +558,9 @@ components: The host name of the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. type: string oauthTokenUrl: - type: string - nullable: true + type: + - string + - 'null' port: description: | The port to connect to on the service provider. If the `service` is `elastic_cloud` (for Elastic Cloud notifications) or one of Nodemailer's well-known email service providers, this property is ignored. If `service` is `other`, this property must be defined. @@ -562,8 +583,9 @@ components: tenantId: description: | The tenant identifier, which is part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true + type: + - string + - 'null' secrets_properties_email: title: Connector secrets properties for an email connector description: Defines secrets for connectors when type is `.email`. @@ -599,11 +621,13 @@ components: description: The type of connector. enum: - .email - example: .email + examples: + - .email name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_email' config_properties_genai: @@ -667,11 +691,13 @@ components: description: The type of connector. enum: - .gen-ai - example: .gen-ai + examples: + - .gen-ai name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_genai' config_properties_index: @@ -684,8 +710,9 @@ components: executionTimeField: description: A field that indicates when the document was indexed. default: null - type: string - nullable: true + type: + - string + - 'null' index: description: The Elasticsearch index to be written to. type: string @@ -710,11 +737,13 @@ components: description: The type of connector. enum: - .index - example: .index + examples: + - .index name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector config_properties_jira: title: Connector request properties for a Jira connector required: @@ -760,11 +789,13 @@ components: description: The type of connector. enum: - .jira - example: .jira + examples: + - .jira name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_jira' config_properties_opsgenie: @@ -805,11 +836,13 @@ components: description: The type of connector. enum: - .opsgenie - example: .opsgenie + examples: + - .opsgenie name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_opsgenie' config_properties_pagerduty: @@ -819,9 +852,11 @@ components: properties: apiUrl: description: The PagerDuty event URL. - type: string - nullable: true - example: https://events.pagerduty.com/v2/enqueue + type: + - string + - 'null' + examples: + - https://events.pagerduty.com/v2/enqueue secrets_properties_pagerduty: title: Connector secrets properties for a PagerDuty connector description: Defines secrets for connectors when type is `.pagerduty`. @@ -851,11 +886,13 @@ components: description: The type of connector. enum: - .pagerduty - example: .pagerduty + examples: + - .pagerduty name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_pagerduty' config_properties_resilient: @@ -901,13 +938,15 @@ components: connector_type_id: description: The type of connector. type: string - example: .resilient + examples: + - .resilient enum: - .resilient name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_resilient' create_connector_request_serverlog: @@ -923,11 +962,13 @@ components: description: The type of connector. enum: - .server-log - example: .server-log + examples: + - .server-log name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector config_properties_servicenow: title: Connector request properties for a ServiceNow ITSM connector required: @@ -998,11 +1039,13 @@ components: description: The type of connector. enum: - .servicenow - example: .servicenow + examples: + - .servicenow name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' config_properties_servicenow_itom: @@ -1050,11 +1093,13 @@ components: description: The type of connector. enum: - .servicenow-itom - example: .servicenow-itom + examples: + - .servicenow-itom name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' create_connector_request_servicenow_sir: @@ -1075,11 +1120,13 @@ components: description: The type of connector. enum: - .servicenow-sir - example: .servicenow-sir + examples: + - .servicenow-sir name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_servicenow' secrets_properties_slack_api: @@ -1106,11 +1153,13 @@ components: description: The type of connector. enum: - .slack_api - example: .slack_api + examples: + - .slack_api name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_slack_api' secrets_properties_slack_webhook: @@ -1137,11 +1186,13 @@ components: description: The type of connector. enum: - .slack - example: .slack + examples: + - .slack name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_slack_webhook' config_properties_swimlane: @@ -1350,11 +1401,13 @@ components: description: The type of connector. enum: - .swimlane - example: .swimlane + examples: + - .swimlane name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_swimlane' secrets_properties_teams: @@ -1382,11 +1435,13 @@ components: description: The type of connector. enum: - .teams - example: .teams + examples: + - .teams name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_teams' config_properties_tines: @@ -1432,11 +1487,13 @@ components: description: The type of connector. enum: - .tines - example: .tines + examples: + - .tines name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_tines' config_properties_torq: @@ -1477,11 +1534,13 @@ components: description: The type of connector. enum: - .torq - example: .torq + examples: + - .torq name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_torq' config_properties_webhook: @@ -1513,8 +1572,9 @@ components: description: | If `true`, a user name and password must be provided for login type authentication. headers: - type: object - nullable: true + type: + - object + - 'null' description: A set of key-value pairs sent as headers with the request. method: type: string @@ -1577,11 +1637,13 @@ components: description: The type of connector. enum: - .webhook - example: .webhook + examples: + - .webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_webhook' config_properties_xmatters: @@ -1592,8 +1654,9 @@ components: configUrl: description: | The request URL for the Elastic Alerts trigger in xMatters. It is applicable only when `usesBasic` is `true`. - type: string - nullable: true + type: + - string + - 'null' usesBasic: description: Specifies whether the connector uses HTTP basic authentication (`true`) or URL authentication (`false`). type: boolean @@ -1633,11 +1696,13 @@ components: description: The type of connector. enum: - .xmatters - example: .xmatters + examples: + - .xmatters name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_xmatters' create_connector_request: @@ -1671,20 +1736,24 @@ components: is_deprecated: type: boolean description: Indicates whether the connector type is deprecated. - example: false + examples: + - false is_missing_secrets: type: boolean description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. - example: false + examples: + - false is_preconfigured: type: boolean description: | Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. - example: false + examples: + - false is_system_action: type: boolean description: Indicates whether the connector is used for system actions. - example: false + examples: + - false connector_response_properties_bedrock: title: Connector response properties for an Amazon Bedrock connector type: object @@ -1721,7 +1790,8 @@ components: type: integer description: | Indicates the number of saved objects that reference the connector. If `is_preconfigured` is true, this value is not calculated. This property is returned only by the get all connectors API. - example: 2 + examples: + - 2 connector_response_properties_cases_webhook: title: Connector request properties for a Webhook - Case Management connector type: object @@ -1997,8 +2067,9 @@ components: - name properties: config: - type: object - nullable: true + type: + - object + - 'null' connector_type_id: type: string description: The type of connector. @@ -2432,7 +2503,8 @@ components: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_cases_webhook' update_connector_request_d3security: @@ -2612,7 +2684,8 @@ components: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: '#/components/schemas/secrets_properties_swimlane' update_connector_request_teams: @@ -2749,7 +2822,8 @@ components: - .torq - .webhook - .xmatters - example: .server-log + examples: + - .server-log examples: create_email_connector_request: summary: Create an email connector. @@ -2932,14 +3006,16 @@ components: properties: error: type: string - example: Unauthorized + examples: + - Unauthorized enum: - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 enum: - 401 '404': @@ -2952,14 +3028,17 @@ components: properties: error: type: string - example: Not Found + examples: + - Not Found enum: - Not Found message: type: string - example: Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found + examples: + - Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found statusCode: type: integer - example: 404 + examples: + - 404 enum: - 404 diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_request.yaml new file mode 100644 index 000000000000..8124aac245ec --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_request.yaml @@ -0,0 +1,10 @@ +summary: Run a PagerDuty connector to trigger an alert. +value: + params: + eventAction: trigger + summary: A brief event summary + links: + - href: http://example.com/pagerduty + text: An example link + customDetails: + my_data_1: test data \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_response.yaml b/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_response.yaml new file mode 100644 index 000000000000..81e941ce52a4 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/examples/run_pagerduty_connector_response.yaml @@ -0,0 +1,8 @@ +summary: Response from running a PagerDuty connector. +value: + connector_id: 45de9f70-954f-4608-b12a-db7cf808e49d + data: + dedup_key: 5115e138b26b484a81eaea779faa6016 + message: Event processed + status: success + status: ok \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/parameters/action_id.yaml b/x-pack/plugins/actions/docs/openapi/components/parameters/action_id.yaml index 3ee0b642c9de..acbc6ab5acd6 100644 --- a/x-pack/plugins/actions/docs/openapi/components/parameters/action_id.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/parameters/action_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the action. required: true schema: type: string - example: c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad + examples: + - c55b6eb0-6bad-11eb-9f3b-611eebc6c3ad diff --git a/x-pack/plugins/actions/docs/openapi/components/parameters/connector_id.yaml b/x-pack/plugins/actions/docs/openapi/components/parameters/connector_id.yaml index d98c2cec803f..fdf1487e626a 100644 --- a/x-pack/plugins/actions/docs/openapi/components/parameters/connector_id.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/parameters/connector_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the connector. required: true schema: type: string - example: df770e30-8b8b-11ed-a780-3b746c987a81 + examples: + - df770e30-8b8b-11ed-a780-3b746c987a81 diff --git a/x-pack/plugins/actions/docs/openapi/components/parameters/space_id.yaml b/x-pack/plugins/actions/docs/openapi/components/parameters/space_id.yaml index 0a9fba457e3e..45787e844cae 100644 --- a/x-pack/plugins/actions/docs/openapi/components/parameters/space_id.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/parameters/space_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the space. If `/s/` and the identifier are omitte required: true schema: type: string - example: default + examples: + - default diff --git a/x-pack/plugins/actions/docs/openapi/components/responses/400.yaml b/x-pack/plugins/actions/docs/openapi/components/responses/400.yaml index 263623dd1fb4..4f8890737ff4 100644 --- a/x-pack/plugins/actions/docs/openapi/components/responses/400.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/responses/400.yaml @@ -6,10 +6,13 @@ content: properties: error: type: string - example: Bad Request + examples: + - Bad Request message: type: string - example: "error validating action type config: [index]: expected value of type [string] but got [undefined]" + examples: + - "error validating action type config: [index]: expected value of type [string] but got [undefined]" statusCode: type: integer - example: 400 \ No newline at end of file + examples: + - 400 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/responses/401.yaml b/x-pack/plugins/actions/docs/openapi/components/responses/401.yaml index ff5cbfd4c276..78b77b3ab5f4 100644 --- a/x-pack/plugins/actions/docs/openapi/components/responses/401.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/responses/401.yaml @@ -7,13 +7,15 @@ content: properties: error: type: string - example: Unauthorized + examples: + - Unauthorized enum: - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 enum: - 401 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/responses/404.yaml b/x-pack/plugins/actions/docs/openapi/components/responses/404.yaml index 56964c6015c8..d4cf816f5903 100644 --- a/x-pack/plugins/actions/docs/openapi/components/responses/404.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/responses/404.yaml @@ -7,14 +7,17 @@ content: properties: error: type: string - example: Not Found + examples: + - Not Found enum: - Not Found message: type: string - example: "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" + examples: + - "Saved object [action/baf33fc0-920c-11ed-b36a-874bd1548a00] not found" statusCode: type: integer - example: 404 + examples: + - 404 enum: - 404 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml index 43945fbb241a..81c94bd3e880 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_cases_webhook.yaml @@ -22,7 +22,8 @@ properties: connector. The JSON is validated once the Mustache variables have been placed when the REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: {"body": {{{case.comment}}}} + examples: + - {"body": {{{case.comment}}}} createCommentMethod: type: string description: > @@ -40,7 +41,8 @@ properties: You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts setting`, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}}/comment createIncidentJson: type: string description: > @@ -52,7 +54,8 @@ properties: connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + examples: + - {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} createIncidentMethod: type: string description: > @@ -86,7 +89,8 @@ properties: variables have been placed when REST method runs. Manually ensure that the JSON is valid, disregarding the Mustache variables, so the later validation will pass. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.id}}} hasAuth: type: boolean description: If true, a username and password for login type authentication must be provided. @@ -107,7 +111,8 @@ properties: connector. The JSON is validated after the Mustache variables have been placed when REST method runs. Manually ensure that the JSON is valid to avoid future validation errors; disregard Mustache variables during your review. - example: {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} + examples: + - {"fields": {"summary": {{{case.title}}},"description": {{{case.description}}},"labels": {{{case.tags}}}}} updateIncidentMethod: type: string description: > @@ -124,12 +129,14 @@ properties: The REST API URL to update the case by ID in the third-party system. You can use a variable to add the external system ID to the URL. If you are using the `xpack.actions.allowedHosts` setting, add the hostname to the allowed hosts. - example: https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} + examples: + - https://testing-jira.atlassian.net/rest/api/2/issue/{{{external.system.ID}}} viewIncidentUrl: type: string description: > The URL to view the case in the external system. You can use variables to add the external system ID or external system title to the URL. - example: https://testing-jira.atlassian.net/browse/{{{external.system.title}}} + examples: + - https://testing-jira.atlassian.net/browse/{{{external.system.title}}} diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml index 6d3618e2bba2..202f4022a6fb 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_email.yaml @@ -8,8 +8,9 @@ properties: description: > The client identifier, which is a part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true + type: + - "string" + - "null" from: description: > The from address for all emails sent by the connector. It must be specified in `user@host-name` format. @@ -27,8 +28,9 @@ properties: type: string oauthTokenUrl: # description: TBD - type: string - nullable: true + type: + - "string" + - "null" port: description: > The port to connect to on the service provider. @@ -55,5 +57,6 @@ properties: description: > The tenant identifier, which is part of OAuth 2.0 client credentials authentication, in GUID format. If `service` is `exchange_server`, this property is required. - type: string - nullable: true \ No newline at end of file + type: + - "string" + - "null" \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml index 6c335b166d20..f6d3af59b493 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_index.yaml @@ -7,8 +7,9 @@ properties: executionTimeField: description: A field that indicates when the document was indexed. default: null - type: string - nullable: true + type: + - "string" + - "null" index: description: The Elasticsearch index to be written to. type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml index 562557f548ec..bfbec7b46190 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_pagerduty.yaml @@ -4,6 +4,8 @@ type: object properties: apiUrl: description: The PagerDuty event URL. - type: string - nullable: true - example: https://events.pagerduty.com/v2/enqueue \ No newline at end of file + type: + - "string" + - "null" + examples: + - https://events.pagerduty.com/v2/enqueue \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml index fe45366eca26..601d41066657 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_webhook.yaml @@ -27,8 +27,9 @@ properties: description: > If `true`, a user name and password must be provided for login type authentication. headers: - type: object - nullable: true + type: + - "object" + - "null" description: A set of key-value pairs sent as headers with the request. method: type: string diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml index 350e96f3aa63..3393c11ecd90 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/config_properties_xmatters.yaml @@ -6,8 +6,9 @@ properties: description: > The request URL for the Elastic Alerts trigger in xMatters. It is applicable only when `usesBasic` is `true`. - type: string - nullable: true + type: + - "string" + - "null" usesBasic: description: Specifies whether the connector uses HTTP basic authentication (`true`) or URL authentication (`false`). type: boolean diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml index a397e668102a..da741478864b 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/connector_response_properties_serverlog.yaml @@ -8,8 +8,9 @@ required: - name properties: config: - type: object - nullable: true + type: + - "object" + - "null" connector_type_id: type: string description: The type of 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 5d0bc42ab831..dff10fcc778d 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 @@ -24,4 +24,5 @@ enum: - .torq - .webhook - .xmatters -example: .server-log \ No newline at end of file +examples: + - .server-log \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_bedrock.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_bedrock.yaml index 2acc21bfbfac..e8feecb0051c 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_bedrock.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_bedrock.yaml @@ -14,10 +14,12 @@ properties: description: The type of connector. enum: - .bedrock - example: .bedrock + examples: + - .bedrock name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_bedrock.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml index bcbe840c0351..0cd030d74080 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_cases_webhook.yaml @@ -15,10 +15,12 @@ properties: description: The type of connector. enum: - .cases-webhook - example: .cases-webhook + examples: + - .cases-webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_d3security.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_d3security.yaml index 39cdda80b7dd..6b5389cc80f3 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_d3security.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_d3security.yaml @@ -15,10 +15,12 @@ properties: description: The type of connector. enum: - .d3security - example: .d3security + examples: + - .d3security name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_d3security.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml index 89f0b79c4e74..1f1c6c079770 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_email.yaml @@ -18,10 +18,12 @@ properties: description: The type of connector. enum: - .email - example: .email + examples: + - .email name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_email.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_genai.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_genai.yaml index 95d65bdb8091..725f842f9109 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_genai.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_genai.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .gen-ai - example: .gen-ai + examples: + - .gen-ai name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_genai.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml index 26d6e118c1fe..ad8e9be9a41d 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_index.yaml @@ -13,8 +13,10 @@ properties: description: The type of connector. enum: - .index - example: .index + examples: + - .index name: type: string description: The display name for the connector. - example: my-connector \ No newline at end of file + examples: + - my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml index 5b6077e875b2..95ccaa5b2ec6 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_jira.yaml @@ -14,10 +14,12 @@ properties: description: The type of connector. enum: - .jira - example: .jira + examples: + - .jira name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_jira.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml index 6de1296dac43..51c29f5cdd8f 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_opsgenie.yaml @@ -14,10 +14,12 @@ properties: description: The type of connector. enum: - .opsgenie - example: .opsgenie + examples: + - .opsgenie name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_opsgenie.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml index 498488299afd..66ffc61d30f3 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_pagerduty.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .pagerduty - example: .pagerduty + examples: + - .pagerduty name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_pagerduty.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml index c3f766625b7d..60467336c0d9 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_resilient.yaml @@ -12,12 +12,14 @@ properties: connector_type_id: description: The type of connector. type: string - example: .resilient + examples: + - .resilient enum: - .resilient name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_resilient.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml index eac0a0d65b69..0cb85403663c 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_serverlog.yaml @@ -10,8 +10,10 @@ properties: description: The type of connector. enum: - .server-log - example: .server-log + examples: + - .server-log name: type: string description: The display name for the connector. - example: my-connector \ No newline at end of file + examples: + - my-connector \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml index e03303dcada4..b0f35483cc39 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .servicenow - example: .servicenow + examples: + - .servicenow name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml index 70a4c05c9652..bfbeb231ca7d 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_itom.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .servicenow-itom - example: .servicenow-itom + examples: + - .servicenow-itom name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml index 4d247c456f3e..37519eb63f27 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_servicenow_sir.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .servicenow-sir - example: .servicenow-sir + examples: + - .servicenow-sir name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_servicenow.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_api.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_api.yaml index a16ba7416e7b..07dbadbef989 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_api.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_api.yaml @@ -11,10 +11,12 @@ properties: description: The type of connector. enum: - .slack_api - example: .slack_api + examples: + - .slack_api name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_slack_api.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_webhook.yaml index 1c046cc3f000..3e884daa6e3b 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_slack_webhook.yaml @@ -11,10 +11,12 @@ properties: description: The type of connector. enum: - .slack - example: .slack + examples: + - .slack name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_slack_webhook.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml index 3de4f5ecbcce..633438a721ee 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_swimlane.yaml @@ -14,10 +14,12 @@ properties: description: The type of connector. enum: - .swimlane - example: .swimlane + examples: + - .swimlane name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml index 5e0d449bf554..787f057c09ce 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_teams.yaml @@ -11,10 +11,12 @@ properties: description: The type of connector. enum: - .teams - example: .teams + examples: + - .teams name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_teams.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml index 224c3e03c436..c5333c8acc47 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_tines.yaml @@ -15,10 +15,12 @@ properties: description: The type of connector. enum: - .tines - example: .tines + examples: + - .tines name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_tines.yaml' \ 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 index 934f9c9c1b39..a4ab3cc92aa0 100644 --- 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 @@ -15,10 +15,12 @@ properties: description: The type of connector. enum: - .torq - example: .torq + examples: + - .torq name: type: string description: The display name for the connector. - example: my-connector + examples: + - 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/create_connector_request_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml index e0ead115d48d..30e9663da8d9 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_webhook.yaml @@ -15,10 +15,12 @@ properties: description: The type of connector. enum: - .webhook - example: .webhook + examples: + - .webhook name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml index 13213d39561b..753888b16ae5 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/create_connector_request_xmatters.yaml @@ -16,10 +16,12 @@ properties: description: The type of connector. enum: - .xmatters - example: .xmatters + examples: + - .xmatters name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_xmatters.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/is_deprecated.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/is_deprecated.yaml index 75fb1efe2f58..ac0a26102eed 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/is_deprecated.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/is_deprecated.yaml @@ -1,3 +1,4 @@ type: boolean description: Indicates whether the connector type is deprecated. -example: false \ No newline at end of file +examples: + - false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/is_missing_secrets.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/is_missing_secrets.yaml index cad03a44f862..a7ad3f9542b3 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/is_missing_secrets.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/is_missing_secrets.yaml @@ -1,3 +1,4 @@ type: boolean description: Indicates whether secrets are missing for the connector. Secrets configuration properties vary depending on the connector type. -example: false \ No newline at end of file +examples: + - false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/is_preconfigured.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/is_preconfigured.yaml index e38741c83718..d3f711c22939 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/is_preconfigured.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/is_preconfigured.yaml @@ -2,4 +2,5 @@ type: boolean description: > Indicates whether it is a preconfigured connector. If true, the `config` and `is_missing_secrets` properties are omitted from the response. -example: false \ No newline at end of file +examples: + - false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/is_system_action.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/is_system_action.yaml index fd0dd06ef5ff..5a78f4676646 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/is_system_action.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/is_system_action.yaml @@ -1,3 +1,4 @@ type: boolean description: Indicates whether the connector is used for system actions. -example: false \ No newline at end of file +examples: + - false \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/referenced_by_count.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/referenced_by_count.yaml index 61579fa3dc6c..0a65bf9a854f 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/referenced_by_count.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/referenced_by_count.yaml @@ -3,4 +3,5 @@ description: > Indicates the number of saved objects that reference the connector. If `is_preconfigured` is true, this value is not calculated. This property is returned only by the get all connectors API. -example: 2 \ No newline at end of file +examples: + - 2 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_acknowledge_resolve_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_acknowledge_resolve_pagerduty.yaml new file mode 100644 index 000000000000..d5e9087cdb7b --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_acknowledge_resolve_pagerduty.yaml @@ -0,0 +1,17 @@ +title: PagerDuty connector parameters +description: Test an action that acknowledges or resolves a PagerDuty alert. +type: object +required: + - dedupKey + - eventAction +properties: + dedupKey: + description: The deduplication key for the PagerDuty alert. + type: string + maxLength: 255 + eventAction: + description: The type of event. + type: string + enum: + - acknowledge + - resolve \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_trigger_pagerduty.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_trigger_pagerduty.yaml new file mode 100644 index 000000000000..75a59af15626 --- /dev/null +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_params_trigger_pagerduty.yaml @@ -0,0 +1,69 @@ +title: PagerDuty connector parameters +description: Test an action that triggers a PagerDuty alert. +type: object +required: + - eventAction +properties: + class: + description: The class or type of the event. + type: string + examples: + - cpu load + component: + description: The component of the source machine that is responsible for the event. + type: string + examples: + - eth0 + customDetails: + description: Additional details to add to the event. + type: object + dedupKey: + description: > + All actions sharing this key will be associated with the same PagerDuty alert. + This value is used to correlate trigger and resolution. + type: string + maxLength: 255 + eventAction: + description: The type of event. + type: string + enum: + - trigger + group: + description: The logical grouping of components of a service. + type: string + examples: + - app-stack + links: + description: A list of links to add to the event. + type: array + items: + type: object + properties: + href: + description: The URL for the link. + type: string + text: + description: A plain text description of the purpose of the link. + type: string + severity: + description: The severity of the event on the affected system. + type: string + enum: + - critical + - error + - info + - warning + default: info + source: + description: > + The affected system, such as a hostname or fully qualified domain name. + Defaults to the Kibana saved object id of the action. + type: string + summary: + description: A summery of the event. + type: string + maxLength: 1024 + timestamp: + description: An ISO-8601 timestamp that indicates when the event was detected or generated. + type: string + format: date-time \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_request.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_request.yaml index 7602693cebe5..13b0623a01ab 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_request.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_request.yaml @@ -6,9 +6,11 @@ required: properties: params: oneOf: + - $ref: 'run_connector_params_acknowledge_resolve_pagerduty.yaml' - $ref: 'run_connector_params_documents.yaml' - $ref: 'run_connector_params_message_email.yaml' - $ref: 'run_connector_params_message_serverlog.yaml' + - $ref: 'run_connector_params_trigger_pagerduty.yaml' - title: Subaction parameters description: Test an action that involves a subaction. oneOf: diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_createalert.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_createalert.yaml index e739a9ed6c91..a53560951361 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_createalert.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_createalert.yaml @@ -30,7 +30,8 @@ properties: type: object description: The custom properties of the alert. additionalProperties: true - example: {"key1":"value1","key2":"value2"} + examples: + - {"key1":"value1","key2":"value2"} entity: type: string description: The domain of the alert. For example, the application or server name. diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_fieldsbyissuetype.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_fieldsbyissuetype.yaml index e8c8869e7d68..6c39957c29fc 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_fieldsbyissuetype.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_fieldsbyissuetype.yaml @@ -18,5 +18,6 @@ properties: id: type: string description: The Jira issue type identifier. - example: 10024 + examples: + - 10024 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_getincident.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_getincident.yaml index 666c0257f68b..7a16f3d9f829 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_getincident.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_getincident.yaml @@ -18,4 +18,5 @@ properties: externalId: type: string description: The Jira, ServiceNow ITSM, or ServiceNow SecOps issue identifier. - example: 71778 + examples: + - 71778 diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_issue.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_issue.yaml index 56ee923b4006..3743e7fa90bd 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_issue.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/run_connector_subaction_issue.yaml @@ -17,4 +17,5 @@ properties: id: type: string description: The Jira issue identifier. - example: 71778 \ No newline at end of file + examples: + - 71778 \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml index 66250b31a94e..9201a1b1e1d7 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_cases_webhook.yaml @@ -9,6 +9,7 @@ properties: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_cases_webhook.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml index 81321351b74e..771625841a04 100644 --- a/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml +++ b/x-pack/plugins/actions/docs/openapi/components/schemas/update_connector_request_swimlane.yaml @@ -10,6 +10,7 @@ properties: name: type: string description: The display name for the connector. - example: my-connector + examples: + - my-connector secrets: $ref: 'secrets_properties_swimlane.yaml' \ No newline at end of file diff --git a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml index bdbf408de3e1..d082d91a2a4e 100644 --- a/x-pack/plugins/actions/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/actions/docs/openapi/entrypoint.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Connectors description: OpenAPI schema for Connectors endpoints - version: '0.1' + version: '0.2' contact: name: Connectors Team license: @@ -51,7 +51,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/actions/docs/openapi/entrypoint_serverless.yaml b/x-pack/plugins/actions/docs/openapi/entrypoint_serverless.yaml index 3503221c4e30..4780a65da652 100644 --- a/x-pack/plugins/actions/docs/openapi/entrypoint_serverless.yaml +++ b/x-pack/plugins/actions/docs/openapi/entrypoint_serverless.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Connectors description: OpenAPI schema for connectors in Serverless projects - version: '0.1' + version: '0.2' contact: name: Connectors Team license: @@ -30,6 +30,7 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - apiKeyAuth: [] diff --git a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}.yaml b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}.yaml index e4b8e1c46864..6464b9592436 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}.yaml @@ -51,7 +51,8 @@ post: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: diff --git a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}@_execute.yaml b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}@_execute.yaml index 577a57fbb5d9..a276f30292da 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}@_execute.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector@{connectorid}@_execute.yaml @@ -23,6 +23,8 @@ post: $ref: '../components/examples/run_index_connector_request.yaml' runJiraConnectorRequest: $ref: '../components/examples/run_jira_connector_request.yaml' + runPagerDutyConnectorRequest: + $ref: '../components/examples/run_pagerduty_connector_request.yaml' runServerLogConnectorRequest: $ref: '../components/examples/run_server_log_connector_request.yaml' runServiceNowITOMConnectorRequest: @@ -65,6 +67,8 @@ post: $ref: '../components/examples/run_index_connector_response.yaml' runJiraConnectorResponse: $ref: '../components/examples/run_jira_connector_response.yaml' + runPagerDutyConnectorResponse: + $ref: '../components/examples/run_pagerduty_connector_response.yaml' runServerLogConnectorResponse: $ref: '../components/examples/run_server_log_connector_response.yaml' runServiceNowITOMConnectorResponse: diff --git a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector_types.yaml b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector_types.yaml index 530fed05e304..94dbb727eea4 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/api@actions@connector_types.yaml @@ -24,37 +24,41 @@ get: enabled: type: boolean description: Indicates whether the connector type is enabled in Kibana. - example: true + examples: + - true enabled_in_config: type: boolean description: Indicates whether the connector type is enabled in the Kibana configuration file. - example: true + examples: + - true enabled_in_license: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: $ref: '../components/schemas/connector_types.yaml' is_system_action_type: type: boolean - example: false + examples: + - false minimum_license_required: type: string description: The license that is required to use the connector type. - example: basic + examples: + - basic name: type: string description: The name of the connector type. - example: Index + examples: + - Index supported_feature_ids: type: array description: The features that are supported by the connector type. items: $ref: '../components/schemas/features.yaml' - example: - - alerting - - cases - - siem + examples: + - [alerting, cases, siem] examples: getConnectorTypesServerlessResponse: $ref: '../components/examples/get_connector_types_generativeai_response.yaml' 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 1d014404a643..27351f0954ee 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 @@ -59,7 +59,8 @@ post: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml index 86ef1cd5460f..9a0fababdf16 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@connector_types.yaml @@ -27,34 +27,37 @@ get: enabled: type: boolean description: Indicates whether the connector type is enabled in Kibana. - example: true + examples: + - true enabled_in_config: type: boolean description: Indicates whether the connector type is enabled in the Kibana `.yml` file. - example: true + examples: + - true enabled_in_license: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: $ref: '../components/schemas/connector_types.yaml' minimum_license_required: type: string description: The license that is required to use the connector type. - example: basic + examples: + - basic name: type: string description: The name of the connector type. - example: Index + examples: + - Index supported_feature_ids: type: array description: The Kibana features that are supported by the connector type. items: $ref: '../components/schemas/features.yaml' - example: - - alerting - - uptime - - siem + examples: + - [alerting, uptime, siem] examples: getConnectorTypesResponse: $ref: '../components/examples/get_connector_types_response.yaml' diff --git a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@list_action_types.yaml b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@list_action_types.yaml index edda7d4aca31..6bc2b9e5e53a 100644 --- a/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@list_action_types.yaml +++ b/x-pack/plugins/actions/docs/openapi/paths/s@{spaceid}@api@actions@list_action_types.yaml @@ -28,7 +28,8 @@ get: enabledInLicense: type: boolean description: Indicates whether the connector is enabled in the license. - example: true + examples: + - true id: type: string description: The unique identifier for the connector type. diff --git a/x-pack/plugins/actions/server/lib/gen_ai_token_tracking.ts b/x-pack/plugins/actions/server/lib/gen_ai_token_tracking.ts index 7c104177ea36..866580e8e7b3 100644 --- a/x-pack/plugins/actions/server/lib/gen_ai_token_tracking.ts +++ b/x-pack/plugins/actions/server/lib/gen_ai_token_tracking.ts @@ -42,6 +42,7 @@ export const getGenAiTokenTracking = async ({ try { const { total, prompt, completion } = await getTokenCountFromInvokeStream({ responseStream: result.data.pipe(new PassThrough()), + actionTypeId, body: (validatedParams as { subActionParams: InvokeBody }).subActionParams, logger, }); diff --git a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.test.ts b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.test.ts index 3c0dd66130f3..2d8f86b88172 100644 --- a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.test.ts +++ b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.test.ts @@ -7,20 +7,15 @@ import { Transform } from 'stream'; import { getTokenCountFromInvokeStream } from './get_token_count_from_invoke_stream'; import { loggerMock } from '@kbn/logging-mocks'; +import { EventStreamCodec } from '@smithy/eventstream-codec'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; -interface StreamMock { - write: (data: string) => void; - fail: () => void; - complete: () => void; - transform: Transform; -} - -function createStreamMock(): StreamMock { +function createStreamMock() { const transform: Transform = new Transform({}); return { - write: (data: string) => { - transform.push(`${data}\n`); + write: (data: unknown) => { + transform.push(data); }, fail: () => { transform.emit('error', new Error('Stream failed')); @@ -34,7 +29,10 @@ function createStreamMock(): StreamMock { } const logger = loggerMock.create(); describe('getTokenCountFromInvokeStream', () => { - let stream: StreamMock; + beforeEach(() => { + jest.resetAllMocks(); + }); + let stream: ReturnType; const body = { messages: [ { @@ -48,36 +46,79 @@ describe('getTokenCountFromInvokeStream', () => { ], }; + const chunk = { + object: 'chat.completion.chunk', + choices: [ + { + delta: { + content: 'Single.', + }, + }, + ], + }; + const PROMPT_TOKEN_COUNT = 34; const COMPLETION_TOKEN_COUNT = 2; + describe('OpenAI stream', () => { + beforeEach(() => { + stream = createStreamMock(); + stream.write(`data: ${JSON.stringify(chunk)}`); + }); - beforeEach(() => { - stream = createStreamMock(); - stream.write('Single'); - }); - - describe('when a stream completes', () => { - beforeEach(async () => { + it('counts the prompt + completion tokens for OpenAI response', async () => { stream.complete(); - }); - it('counts the prompt tokens', async () => { const tokens = await getTokenCountFromInvokeStream({ responseStream: stream.transform, body, logger, + actionTypeId: '.gen-ai', }); expect(tokens.prompt).toBe(PROMPT_TOKEN_COUNT); expect(tokens.completion).toBe(COMPLETION_TOKEN_COUNT); expect(tokens.total).toBe(PROMPT_TOKEN_COUNT + COMPLETION_TOKEN_COUNT); }); + it('resolves the promise with the correct prompt tokens', async () => { + const tokenPromise = getTokenCountFromInvokeStream({ + responseStream: stream.transform, + body, + logger, + actionTypeId: '.gen-ai', + }); + + stream.fail(); + + await expect(tokenPromise).resolves.toEqual({ + prompt: PROMPT_TOKEN_COUNT, + total: PROMPT_TOKEN_COUNT + COMPLETION_TOKEN_COUNT, + completion: COMPLETION_TOKEN_COUNT, + }); + expect(logger.error).toHaveBeenCalled(); + }); }); + describe('Bedrock stream', () => { + beforeEach(() => { + stream = createStreamMock(); + stream.write(encodeBedrockResponse('Simple.')); + }); - describe('when a stream fails', () => { + it('counts the prompt + completion tokens for OpenAI response', async () => { + stream.complete(); + const tokens = await getTokenCountFromInvokeStream({ + responseStream: stream.transform, + body, + logger, + actionTypeId: '.bedrock', + }); + expect(tokens.prompt).toBe(PROMPT_TOKEN_COUNT); + expect(tokens.completion).toBe(COMPLETION_TOKEN_COUNT); + expect(tokens.total).toBe(PROMPT_TOKEN_COUNT + COMPLETION_TOKEN_COUNT); + }); it('resolves the promise with the correct prompt tokens', async () => { const tokenPromise = getTokenCountFromInvokeStream({ responseStream: stream.transform, body, logger, + actionTypeId: '.bedrock', }); stream.fail(); @@ -91,3 +132,16 @@ describe('getTokenCountFromInvokeStream', () => { }); }); }); + +function encodeBedrockResponse(completion: string) { + return new EventStreamCodec(toUtf8, fromUtf8).encode({ + headers: {}, + body: Uint8Array.from( + Buffer.from( + JSON.stringify({ + bytes: Buffer.from(JSON.stringify({ completion })).toString('base64'), + }) + ) + ), + }); +} diff --git a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts index 594fec89d93c..dfb4bae69f8c 100644 --- a/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts +++ b/x-pack/plugins/actions/server/lib/get_token_count_from_invoke_stream.ts @@ -9,6 +9,8 @@ import { Logger } from '@kbn/logging'; import { encode } from 'gpt-tokenizer'; import { Readable } from 'stream'; import { finished } from 'stream/promises'; +import { EventStreamCodec } from '@smithy/eventstream-codec'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; export interface InvokeBody { messages: Array<{ @@ -26,10 +28,12 @@ export interface InvokeBody { * @param logger the logger */ export async function getTokenCountFromInvokeStream({ + actionTypeId, responseStream, body, logger, }: { + actionTypeId: string; responseStream: Readable; body: InvokeBody; logger: Logger; @@ -47,9 +51,37 @@ export async function getTokenCountFromInvokeStream({ .join('\n') ).length; - let responseBody: string = ''; + const parser = actionTypeId === '.bedrock' ? parseBedrockStream : parseOpenAIStream; + const parsedResponse = await parser(responseStream, logger); + + const completionTokens = encode(parsedResponse).length; + return { + prompt: promptTokens, + completion: completionTokens, + total: promptTokens + completionTokens, + }; +} + +type StreamParser = (responseStream: Readable, logger: Logger) => Promise; - responseStream.on('data', (chunk: string) => { +const parseBedrockStream: StreamParser = async (responseStream, logger) => { + const responseBuffer: Uint8Array[] = []; + responseStream.on('data', (chunk) => { + // special encoding for bedrock, do not attempt to convert to string + responseBuffer.push(chunk); + }); + try { + await finished(responseStream); + } catch (e) { + logger.error('An error occurred while calculating streaming response tokens'); + } + return parseBedrockBuffer(responseBuffer); +}; + +const parseOpenAIStream: StreamParser = async (responseStream, logger) => { + let responseBody: string = ''; + responseStream.on('data', (chunk) => { + // no special encoding, can safely use toString and append to responseBody responseBody += chunk.toString(); }); try { @@ -57,12 +89,109 @@ export async function getTokenCountFromInvokeStream({ } catch (e) { logger.error('An error occurred while calculating streaming response tokens'); } + return parseOpenAIResponse(responseBody); +}; - const completionTokens = encode(responseBody).length; +/** + * Parses a Bedrock buffer from an array of chunks. + * + * @param {Uint8Array[]} chunks - Array of Uint8Array chunks to be parsed. + * @returns {string} - Parsed string from the Bedrock buffer. + */ +const parseBedrockBuffer = (chunks: Uint8Array[]): string => { + // Initialize an empty Uint8Array to store the concatenated buffer. + let bedrockBuffer: Uint8Array = new Uint8Array(0); - return { - prompt: promptTokens, - completion: completionTokens, - total: promptTokens + completionTokens, - }; + // Map through each chunk to process the Bedrock buffer. + return chunks + .map((chunk) => { + // Concatenate the current chunk to the existing buffer. + bedrockBuffer = concatChunks(bedrockBuffer, chunk); + // Get the length of the next message in the buffer. + let messageLength = getMessageLength(bedrockBuffer); + // Initialize an array to store fully formed message chunks. + const buildChunks = []; + // Process the buffer until no complete messages are left. + while (bedrockBuffer.byteLength > 0 && bedrockBuffer.byteLength >= messageLength) { + // Extract a chunk of the specified length from the buffer. + const extractedChunk = bedrockBuffer.slice(0, messageLength); + // Add the extracted chunk to the array of fully formed message chunks. + buildChunks.push(extractedChunk); + // Remove the processed chunk from the buffer. + bedrockBuffer = bedrockBuffer.slice(messageLength); + // Get the length of the next message in the updated buffer. + messageLength = getMessageLength(bedrockBuffer); + } + + const awsDecoder = new EventStreamCodec(toUtf8, fromUtf8); + + // Decode and parse each message chunk, extracting the 'completion' property. + return buildChunks + .map((bChunk) => { + const event = awsDecoder.decode(bChunk); + const body = JSON.parse( + Buffer.from(JSON.parse(new TextDecoder().decode(event.body)).bytes, 'base64').toString() + ); + return body.completion; + }) + .join(''); + }) + .join(''); +}; + +/** + * Concatenates two Uint8Array buffers. + * + * @param {Uint8Array} a - First buffer. + * @param {Uint8Array} b - Second buffer. + * @returns {Uint8Array} - Concatenated buffer. + */ +function concatChunks(a: Uint8Array, b: Uint8Array): Uint8Array { + const newBuffer = new Uint8Array(a.length + b.length); + // Copy the contents of the first buffer to the new buffer. + newBuffer.set(a); + // Copy the contents of the second buffer to the new buffer starting from the end of the first buffer. + newBuffer.set(b, a.length); + return newBuffer; +} + +/** + * Gets the length of the next message from the buffer. + * + * @param {Uint8Array} buffer - Buffer containing the message. + * @returns {number} - Length of the next message. + */ +function getMessageLength(buffer: Uint8Array): number { + // If the buffer is empty, return 0. + if (buffer.byteLength === 0) return 0; + // Create a DataView to read the Uint32 value at the beginning of the buffer. + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + // Read and return the Uint32 value (message length). + return view.getUint32(0, false); } + +const parseOpenAIResponse = (responseBody: string) => + responseBody + .split('\n') + .filter((line) => { + return line.startsWith('data: ') && !line.endsWith('[DONE]'); + }) + .map((line) => { + return JSON.parse(line.replace('data: ', '')); + }) + .filter( + ( + line + ): line is { + choices: Array<{ + delta: { content?: string; function_call?: { name?: string; arguments: string } }; + }>; + } => { + return 'object' in line && line.object === 'chat.completion.chunk'; + } + ) + .reduce((prev, line) => { + const msg = line.choices[0].delta!; + prev += msg.content || ''; + return prev; + }, ''); diff --git a/x-pack/plugins/aiops/public/application/utils/url_state.ts b/x-pack/plugins/aiops/public/application/url_state/common.ts similarity index 71% rename from x-pack/plugins/aiops/public/application/utils/url_state.ts rename to x-pack/plugins/aiops/public/application/url_state/common.ts index 22a32a3d610e..8ca9ec848150 100644 --- a/x-pack/plugins/aiops/public/application/utils/url_state.ts +++ b/x-pack/plugins/aiops/public/application/url_state/common.ts @@ -38,21 +38,3 @@ export const getDefaultAiOpsListState = ( filters: [], ...overrides, }); - -export interface LogCategorizationPageUrlState { - pageKey: 'logCategorization'; - pageUrlState: LogCategorizationAppState; -} - -export interface LogCategorizationAppState extends AiOpsFullIndexBasedAppState { - field: string | undefined; -} - -export const getDefaultLogCategorizationAppState = ( - overrides?: Partial -): LogCategorizationAppState => { - return { - field: undefined, - ...getDefaultAiOpsListState(overrides), - }; -}; diff --git a/x-pack/plugins/aiops/public/application/url_state/log_pattern_analysis.ts b/x-pack/plugins/aiops/public/application/url_state/log_pattern_analysis.ts new file mode 100644 index 000000000000..7ea9e1a398e4 --- /dev/null +++ b/x-pack/plugins/aiops/public/application/url_state/log_pattern_analysis.ts @@ -0,0 +1,26 @@ +/* + * 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 { getDefaultAiOpsListState, type AiOpsFullIndexBasedAppState } from './common'; + +export interface LogCategorizationPageUrlState { + pageKey: 'logCategorization'; + pageUrlState: LogCategorizationAppState; +} + +export interface LogCategorizationAppState extends AiOpsFullIndexBasedAppState { + field: string | undefined; +} + +export const getDefaultLogCategorizationAppState = ( + overrides?: Partial +): LogCategorizationAppState => { + return { + field: undefined, + ...getDefaultAiOpsListState(overrides), + }; +}; diff --git a/x-pack/plugins/aiops/public/application/url_state/log_rate_analysis.ts b/x-pack/plugins/aiops/public/application/url_state/log_rate_analysis.ts new file mode 100644 index 000000000000..f7691bc2b9d7 --- /dev/null +++ b/x-pack/plugins/aiops/public/application/url_state/log_rate_analysis.ts @@ -0,0 +1,66 @@ +/* + * 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 { WindowParameters } from '@kbn/aiops-utils'; + +import { getDefaultAiOpsListState, type AiOpsFullIndexBasedAppState } from './common'; + +export interface LogRateAnalysisPageUrlState { + pageKey: 'logRateAnalysis'; + pageUrlState: LogRateAnalysisAppState; +} +/** + * To avoid long urls, we store the window parameters in the url state not with + * their full parameters names but with abbrevations. `windowParametersToAppState` and + * `appStateToWindowParameters` are used to transform the data structure. + */ +export interface LogRateAnalysisAppState extends AiOpsFullIndexBasedAppState { + /** Window parameters */ + wp?: { + /** Baseline minimum value */ + bMin: number; + /** Baseline maximum value */ + bMax: number; + /** Deviation minimum value */ + dMin: number; + /** Deviation maximum value */ + dMax: number; + }; +} + +/** + * Transforms a full window parameters object to the abbreviated url state version. + */ +export const windowParametersToAppState = (wp?: WindowParameters): LogRateAnalysisAppState['wp'] => + wp && { + bMin: wp.baselineMin, + bMax: wp.baselineMax, + dMin: wp.deviationMin, + dMax: wp.deviationMax, + }; + +/** + * Transforms an abbreviated url state version of window parameters to its full version. + */ +export const appStateToWindowParameters = ( + wp: LogRateAnalysisAppState['wp'] +): WindowParameters | undefined => + wp && { + baselineMin: wp.bMin, + baselineMax: wp.bMax, + deviationMin: wp.dMin, + deviationMax: wp.dMax, + }; + +export const getDefaultLogRateAnalysisAppState = ( + overrides?: Partial +): LogRateAnalysisAppState => { + return { + wp: undefined, + ...getDefaultAiOpsListState(overrides), + }; +}; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/categorize_field_actions.ts b/x-pack/plugins/aiops/public/components/log_categorization/categorize_field_actions.ts index 4d0346560546..761948ab8c4f 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/categorize_field_actions.ts +++ b/x-pack/plugins/aiops/public/components/log_categorization/categorize_field_actions.ts @@ -6,22 +6,19 @@ */ import { i18n } from '@kbn/i18n'; -import { - createAction, - ACTION_CATEGORIZE_FIELD, - type CategorizeFieldContext, -} from '@kbn/ui-actions-plugin/public'; +import { createAction } from '@kbn/ui-actions-plugin/public'; import type { CoreStart } from '@kbn/core/public'; +import { ACTION_CATEGORIZE_FIELD, type CategorizeFieldContext } from '@kbn/ml-ui-actions'; import { AiopsPluginStartDeps } from '../../types'; import { showCategorizeFlyout } from './show_flyout'; -export const categorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPluginStartDeps) => +export const createCategorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPluginStartDeps) => createAction({ type: ACTION_CATEGORIZE_FIELD, id: ACTION_CATEGORIZE_FIELD, getDisplayName: () => i18n.translate('xpack.aiops.categorizeFieldAction.displayName', { - defaultMessage: 'Categorize field', + defaultMessage: 'Pattern analysis', }), isCompatible: async ({ field }: CategorizeFieldContext) => { return field.esTypes?.includes('text') === true; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx index 3796af67f8cd..05cca08d2222 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx @@ -30,7 +30,7 @@ import type { } from '../../../../common/api/log_categorization/types'; import { useEuiTheme } from '../../../hooks/use_eui_theme'; -import type { LogCategorizationAppState } from '../../../application/utils/url_state'; +import type { LogCategorizationAppState } from '../../../application/url_state/log_pattern_analysis'; import { MiniHistogram } from '../../mini_histogram'; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/create_categorization_job.tsx b/x-pack/plugins/aiops/public/components/log_categorization/create_categorization_job.tsx new file mode 100644 index 000000000000..66458c511d98 --- /dev/null +++ b/x-pack/plugins/aiops/public/components/log_categorization/create_categorization_job.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; + +import moment from 'moment'; +import { EuiButtonEmpty } from '@elastic/eui'; +import type { DataViewField, DataView } from '@kbn/data-views-plugin/common'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, + type CreateCategorizationADJobContext, +} from '@kbn/ml-ui-actions'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; + +interface Props { + dataView: DataView; + field: DataViewField; + query: QueryDslQueryContainer; + earliest: number | undefined; + latest: number | undefined; +} + +export const CreateCategorizationJobButton: FC = ({ + dataView, + field, + query, + earliest, + latest, +}) => { + const { + uiActions, + application: { capabilities }, + } = useAiopsAppContext(); + + const createADJob = () => { + if (uiActions === undefined) { + return; + } + + const triggerOptions: CreateCategorizationADJobContext = { + dataView, + field, + query, + timeRange: { from: moment(earliest).toISOString(), to: moment(latest).toISOString() }, + }; + uiActions.getTrigger(CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER).exec(triggerOptions); + }; + + if (uiActions === undefined || capabilities.ml.canCreateJob === false) { + return null; + } + + return ( + <> + + + + + ); +}; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/index.ts b/x-pack/plugins/aiops/public/components/log_categorization/index.ts index 550add880274..ace01d4f0338 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/index.ts +++ b/x-pack/plugins/aiops/public/components/log_categorization/index.ts @@ -7,7 +7,7 @@ export type { LogCategorizationAppStateProps } from './log_categorization_app_state'; import { LogCategorizationAppState } from './log_categorization_app_state'; -export { categorizeFieldAction } from './categorize_field_actions'; +export { createCategorizeFieldAction } from './categorize_field_actions'; // required for dynamic import using React.lazy() // eslint-disable-next-line import/no-default-export diff --git a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_flyout.tsx b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_flyout.tsx index a5262393e0ee..1f3eda09132e 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_flyout.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_for_flyout.tsx @@ -29,7 +29,7 @@ import type { Category, SparkLinesPerCategory } from '../../../common/api/log_ca import { type LogCategorizationPageUrlState, getDefaultLogCategorizationAppState, -} from '../../application/utils/url_state'; +} from '../../application/url_state/log_pattern_analysis'; import { createMergedEsQuery } from '../../application/utils/search_utils'; import { useData } from '../../hooks/use_data'; import { useSearch } from '../../hooks/use_search'; @@ -44,6 +44,7 @@ import { TechnicalPreviewBadge } from './technical_preview_badge'; import { LoadingCategorization } from './loading_categorization'; import { useValidateFieldRequest } from './use_validate_category_field'; import { FieldValidationCallout } from './category_validation_callout'; +import { CreateCategorizationJobButton } from './create_categorization_job'; export interface LogCategorizationPageProps { dataView: DataView; @@ -261,17 +262,21 @@ export const LogCategorizationFlyout: FC = ({ + - {loading === true ? : null} - - {loading === false && data !== null && data.categories.length > 0 ? ( void; + /** Optional callback that exposes current window parameters */ + onWindowParametersChange?: (wp?: WindowParameters) => void; /** Identifier to indicate the plugin utilizing the component */ embeddingOrigin: string; } @@ -90,6 +92,7 @@ export const LogRateAnalysisContent: FC = ({ barColorOverride, barHighlightColorOverride, onAnalysisCompleted, + onWindowParametersChange, embeddingOrigin, }) => { const [windowParameters, setWindowParameters] = useState(); @@ -105,6 +108,28 @@ export const LogRateAnalysisContent: FC = ({ setIsBrushCleared(windowParameters === undefined); }, [windowParameters]); + // Window parameters stored in the url state use this components + // `initialAnalysisStart` prop to set the initial params restore from url state. + // To avoid a loop with window parameters being passed around on load, + // the following ref and useEffect are used to check wether it's safe to call + // the `onWindowParametersChange` callback. + const windowParametersTouched = useRef(false); + useEffect(() => { + // Don't continue if window parameters were not touched yet. + // Because they can be reset to `undefined` at a later stage again when a user + // clears the selections, we cannot rely solely on checking if they are + // `undefined`, we need the additional ref to update on the first change. + if (!windowParametersTouched.current && windowParameters === undefined) { + return; + } + + windowParametersTouched.current = true; + + if (onWindowParametersChange) { + onWindowParametersChange(windowParameters); + } + }, [onWindowParametersChange, windowParameters]); + // Checks if `esSearchQuery` is the default empty query passed on from the search bar // and if that's the case fall back to a simpler match all query. const searchQuery = useMemo( diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_page.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_page.tsx index b3c9f256fb2e..4931503b7366 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_page.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_page.tsx @@ -6,22 +6,26 @@ */ import React, { useCallback, useEffect, useState, FC } from 'react'; +import { isEqual } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { EuiFlexGroup, EuiFlexItem, EuiPageBody, EuiPageSection, EuiSpacer } from '@elastic/eui'; import { Filter, FilterStateStore, Query } from '@kbn/es-query'; import { useUrlState, usePageUrlState } from '@kbn/ml-url-state'; - import type { SearchQueryLanguage } from '@kbn/ml-query-utils'; +import type { WindowParameters } from '@kbn/aiops-utils'; + import { useDataSource } from '../../hooks/use_data_source'; import { useAiopsAppContext } from '../../hooks/use_aiops_app_context'; import { useData } from '../../hooks/use_data'; import { useSearch } from '../../hooks/use_search'; import { - getDefaultAiOpsListState, - type AiOpsPageUrlState, -} from '../../application/utils/url_state'; + getDefaultLogRateAnalysisAppState, + appStateToWindowParameters, + windowParametersToAppState, + type LogRateAnalysisPageUrlState, +} from '../../application/url_state/log_rate_analysis'; import { AIOPS_TELEMETRY_ID } from '../../../common/constants'; import { SearchPanel } from '../search_panel'; @@ -40,9 +44,9 @@ export const LogRateAnalysisPage: FC = ({ stickyHistogram }) => { const { currentSelectedSignificantItem, currentSelectedGroup } = useLogRateAnalysisResultsTableRowContext(); - const [aiopsListState, setAiopsListState] = usePageUrlState( - 'AIOPS_INDEX_VIEWER', - getDefaultAiOpsListState() + const [stateFromUrl, setUrlState] = usePageUrlState( + 'logRateAnalysis', + getDefaultLogRateAnalysisAppState() ); const [globalState, setGlobalState] = useUrlState('_g'); @@ -67,20 +71,20 @@ export const LogRateAnalysisPage: FC = ({ stickyHistogram }) => { setSelectedSavedSearch(null); } - setAiopsListState({ - ...aiopsListState, + setUrlState({ + ...stateFromUrl, searchQuery: searchParams.searchQuery, searchString: searchParams.searchString, searchQueryLanguage: searchParams.queryLanguage, filters: searchParams.filters, }); }, - [selectedSavedSearch, aiopsListState, setAiopsListState] + [selectedSavedSearch, stateFromUrl, setUrlState] ); const { searchQueryLanguage, searchString, searchQuery } = useSearch( { dataView, savedSearch }, - aiopsListState + stateFromUrl ); const { timefilter } = useData( @@ -132,6 +136,14 @@ export const LogRateAnalysisPage: FC = ({ stickyHistogram }) => { }); }, [dataService, searchQueryLanguage, searchString]); + const onWindowParametersHandler = (wp?: WindowParameters) => { + if (!isEqual(wp, stateFromUrl.wp)) { + setUrlState({ + wp: windowParametersToAppState(wp), + }); + } + }; + return ( @@ -148,11 +160,13 @@ export const LogRateAnalysisPage: FC = ({ stickyHistogram }) => { /> diff --git a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts index 5714ae5283fb..c1903f6bba8a 100644 --- a/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts +++ b/x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts @@ -33,6 +33,7 @@ import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/ import type { EmbeddableStart } from '@kbn/embeddable-plugin/public'; import type { CasesUiStart } from '@kbn/cases-plugin/public'; import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; +import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; /** * AIOps App Dependencies to be provided via React context. @@ -97,6 +98,10 @@ export interface AiopsAppDependencies { * Used to create lens embeddables. */ lens: LensPublicStart; + /** + * UI actions. + */ + uiActions?: UiActionsStart; /** * Internationalisation service */ diff --git a/x-pack/plugins/aiops/public/hooks/use_search.ts b/x-pack/plugins/aiops/public/hooks/use_search.ts index 609beb6774bc..8c62db36289f 100644 --- a/x-pack/plugins/aiops/public/hooks/use_search.ts +++ b/x-pack/plugins/aiops/public/hooks/use_search.ts @@ -11,7 +11,7 @@ import type { DataView } from '@kbn/data-views-plugin/public'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; import { getEsQueryFromSavedSearch } from '../application/utils/search_utils'; -import type { AiOpsIndexBasedAppState } from '../application/utils/url_state'; +import type { AiOpsIndexBasedAppState } from '../application/url_state/common'; import { useAiopsAppContext } from './use_aiops_app_context'; export const useSearch = ( diff --git a/x-pack/plugins/aiops/public/plugin.tsx b/x-pack/plugins/aiops/public/plugin.tsx index c896ccc7d5b3..12a7f659135a 100755 --- a/x-pack/plugins/aiops/public/plugin.tsx +++ b/x-pack/plugins/aiops/public/plugin.tsx @@ -25,49 +25,38 @@ export class AiopsPlugin core: AiopsCoreSetup, { embeddable, cases, licensing, uiActions }: AiopsPluginSetupDeps ) { - firstValueFrom(licensing.license$).then(async (license) => { - if (license.hasAtLeast('platinum')) { - if (embeddable) { - const { registerEmbeddable } = await import('./embeddable/register_embeddable'); - registerEmbeddable(core, embeddable); - } + Promise.all([ + firstValueFrom(licensing.license$), + import('./embeddable/register_embeddable'), + import('./ui_actions'), + import('./cases/register_change_point_charts_attachment'), + core.getStartServices(), + ]).then( + ([ + license, + { registerEmbeddable }, + { registerAiopsUiActions }, + { registerChangePointChartsAttachment }, + [coreStart, pluginStart], + ]) => { + if (license.hasAtLeast('platinum')) { + if (embeddable) { + registerEmbeddable(core, embeddable); + } - if (uiActions) { - const { registerAiopsUiActions } = await import('./ui_actions'); - registerAiopsUiActions(uiActions, core); - } + if (uiActions) { + registerAiopsUiActions(uiActions, coreStart, pluginStart); + } - if (cases) { - const [coreStart, pluginStart] = await core.getStartServices(); - const { registerChangePointChartsAttachment } = await import( - './cases/register_change_point_charts_attachment' - ); - registerChangePointChartsAttachment(cases, coreStart, pluginStart); + if (cases) { + registerChangePointChartsAttachment(cases, coreStart, pluginStart); + } } } - }); + ); } public start(core: CoreStart, plugins: AiopsPluginStartDeps): AiopsPluginStart { - // importing async to keep the aiops plugin size to a minimum - Promise.all([ - import('@kbn/ui-actions-plugin/public'), - import('./components/log_categorization'), - firstValueFrom(plugins.licensing.license$), - ]).then(([uiActionsImports, { categorizeFieldAction }, license]) => { - if (license.hasAtLeast('platinum')) { - const { ACTION_CATEGORIZE_FIELD, CATEGORIZE_FIELD_TRIGGER } = uiActionsImports; - if (plugins.uiActions.hasAction(ACTION_CATEGORIZE_FIELD)) { - plugins.uiActions.unregisterAction(ACTION_CATEGORIZE_FIELD); - } - - plugins.uiActions.addTriggerAction( - CATEGORIZE_FIELD_TRIGGER, - categorizeFieldAction(core, plugins) - ); - } - }); - return { EmbeddableChangePointChart: getEmbeddableChangePointChart(core, plugins), }; diff --git a/x-pack/plugins/aiops/public/ui_actions/edit_change_point_charts_panel.tsx b/x-pack/plugins/aiops/public/ui_actions/edit_change_point_charts_panel.tsx index ae50937921f3..d9401f6064cb 100644 --- a/x-pack/plugins/aiops/public/ui_actions/edit_change_point_charts_panel.tsx +++ b/x-pack/plugins/aiops/public/ui_actions/edit_change_point_charts_panel.tsx @@ -8,14 +8,16 @@ import type { UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public'; import { i18n } from '@kbn/i18n'; import { ViewMode } from '@kbn/embeddable-plugin/common'; +import type { CoreStart } from '@kbn/core/public'; import { EMBEDDABLE_CHANGE_POINT_CHART_TYPE } from '../../common/constants'; import type { EditChangePointChartsPanelContext } from '../embeddable/types'; -import type { AiopsCoreSetup } from '../plugin'; +import type { AiopsPluginStartDeps } from '../types'; export const EDIT_CHANGE_POINT_CHARTS_ACTION = 'editChangePointChartsPanelAction'; export function createEditChangePointChartsPanelAction( - getStartServices: AiopsCoreSetup['getStartServices'] + coreStart: CoreStart, + pluginStart: AiopsPluginStartDeps ): UiActionsActionDefinition { return { id: 'edit-change-point-charts', @@ -32,8 +34,6 @@ export function createEditChangePointChartsPanelAction( throw new Error('Not possible to execute an action without the embeddable context'); } - const [coreStart, pluginStart] = await getStartServices(); - try { const { resolveEmbeddableChangePointUserInput } = await import( '../embeddable/handle_explicit_input' diff --git a/x-pack/plugins/aiops/public/ui_actions/index.ts b/x-pack/plugins/aiops/public/ui_actions/index.ts index cd00842c662c..14e1879027ff 100644 --- a/x-pack/plugins/aiops/public/ui_actions/index.ts +++ b/x-pack/plugins/aiops/public/ui_actions/index.ts @@ -7,16 +7,33 @@ import type { UiActionsSetup } from '@kbn/ui-actions-plugin/public'; import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; +import { + categorizeFieldTrigger, + CATEGORIZE_FIELD_TRIGGER, +} from '@kbn/ml-ui-actions/src/aiops/ui_actions'; + +import type { CoreStart } from '@kbn/core/public'; +import type { AiopsPluginStartDeps } from '../types'; import { createEditChangePointChartsPanelAction } from './edit_change_point_charts_panel'; -import type { AiopsCoreSetup } from '../plugin'; +import { createCategorizeFieldAction } from '../components/log_categorization'; -export function registerAiopsUiActions(uiActions: UiActionsSetup, core: AiopsCoreSetup) { +export function registerAiopsUiActions( + uiActions: UiActionsSetup, + coreStart: CoreStart, + pluginStart: AiopsPluginStartDeps +) { // Initialize actions const editChangePointChartPanelAction = createEditChangePointChartsPanelAction( - core.getStartServices + coreStart, + pluginStart + ); + // // Register actions and triggers + uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editChangePointChartPanelAction); + + uiActions.registerTrigger(categorizeFieldTrigger); + + uiActions.addTriggerAction( + CATEGORIZE_FIELD_TRIGGER, + createCategorizeFieldAction(coreStart, pluginStart) ); - // Register actions - uiActions.registerAction(editChangePointChartPanelAction); - // Assign and register triggers - uiActions.attachAction(CONTEXT_MENU_TRIGGER, editChangePointChartPanelAction.id); } diff --git a/x-pack/plugins/aiops/tsconfig.json b/x-pack/plugins/aiops/tsconfig.json index 31d68a5a4ab0..4e2e4bfc8a19 100644 --- a/x-pack/plugins/aiops/tsconfig.json +++ b/x-pack/plugins/aiops/tsconfig.json @@ -65,6 +65,7 @@ "@kbn/ml-chi2test", "@kbn/usage-collection-plugin", "@kbn/analytics", + "@kbn/ml-ui-actions", "@kbn/core-http-server", ], "exclude": [ diff --git a/x-pack/plugins/alerting/server/constants/plugin.ts b/x-pack/plugins/alerting/common/constants/plugin.ts similarity index 90% rename from x-pack/plugins/alerting/server/constants/plugin.ts rename to x-pack/plugins/alerting/common/constants/plugin.ts index 05fd33ebf8dd..e8136f257d46 100644 --- a/x-pack/plugins/alerting/server/constants/plugin.ts +++ b/x-pack/plugins/alerting/common/constants/plugin.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { LicenseType } from '@kbn/licensing-plugin/server'; +import type { LicenseType } from '@kbn/licensing-plugin/server'; export const PLUGIN = { ID: 'alerting', diff --git a/x-pack/plugins/alerting/common/maintenance_window.ts b/x-pack/plugins/alerting/common/maintenance_window.ts index 1f5bffea7708..8b7646670cc7 100644 --- a/x-pack/plugins/alerting/common/maintenance_window.ts +++ b/x-pack/plugins/alerting/common/maintenance_window.ts @@ -14,6 +14,13 @@ export enum MaintenanceWindowStatus { Archived = 'archived', } +export const filterStateStore = { + APP_STATE: 'appState', + GLOBAL_STATE: 'globalState', +} as const; + +export type FilterStateStore = typeof filterStateStore[keyof typeof filterStateStore]; + export interface MaintenanceWindowModificationMetadata { createdBy: string | null; updatedBy: string | null; @@ -26,6 +33,23 @@ export interface DateRange { lte: string; } +export interface ScopeQueryFilter { + query?: Record; + meta: Record; + $state?: { + store: FilterStateStore; + }; +} + +export interface ScopedQueryAttributes { + kql: string; + filters: ScopeQueryFilter[]; + dsl?: string; +} + +/** + * @deprecated Use the data/maintenance_window types instead + */ export interface MaintenanceWindowSOProperties { title: string; enabled: boolean; @@ -34,11 +58,18 @@ export interface MaintenanceWindowSOProperties { events: DateRange[]; rRule: RRuleParams; categoryIds?: string[] | null; + scopedQuery?: ScopedQueryAttributes | null; } +/** + * @deprecated Use the data/maintenance_window types instead + */ export type MaintenanceWindowSOAttributes = MaintenanceWindowSOProperties & MaintenanceWindowModificationMetadata; +/** + * @deprecated Use the application/maintenance_window types instead + */ export type MaintenanceWindow = MaintenanceWindowSOAttributes & { status: MaintenanceWindowStatus; eventStartTime: string | null; diff --git a/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/latest.ts b/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/latest.ts new file mode 100644 index 000000000000..6c32b4867cc0 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/latest.ts @@ -0,0 +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. + */ + +export { filterStateStore } from './v1'; +export type { FilterStateStore } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/v1.ts b/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/v1.ts new file mode 100644 index 000000000000..bce6890c22f2 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/alerts_filter_query/constants/v1.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const filterStateStore = { + APP_STATE: 'appState', + GLOBAL_STATE: 'globalState', +} as const; + +export type FilterStateStore = typeof filterStateStore[keyof typeof filterStateStore]; diff --git a/x-pack/plugins/alerting/common/routes/alerts_filter_query/index.ts b/x-pack/plugins/alerting/common/routes/alerts_filter_query/index.ts new file mode 100644 index 000000000000..093299dbe66f --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/alerts_filter_query/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { filterStateStore } from './constants/latest'; +export type { FilterStateStore } from './constants/latest'; +export { alertsFilterQuerySchema } from './schemas/latest'; + +export { filterStateStore as filterStateStoreV1 } from './constants/v1'; +export type { FilterStateStore as FilterStateStoreV1 } from './constants/v1'; +export { alertsFilterQuerySchema as alertsFilterQuerySchemaV1 } from './schemas/v1'; diff --git a/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/latest.ts b/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/latest.ts new file mode 100644 index 000000000000..b9ae85bd590c --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/latest.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { alertsFilterQuerySchema } from './v1'; diff --git a/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/v1.ts new file mode 100644 index 000000000000..08614efb96b7 --- /dev/null +++ b/x-pack/plugins/alerting/common/routes/alerts_filter_query/schemas/v1.ts @@ -0,0 +1,28 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { filterStateStore } from '..'; + +export const alertsFilterQuerySchema = schema.object({ + kql: schema.string(), + filters: schema.arrayOf( + schema.object({ + query: schema.maybe(schema.recordOf(schema.string(), schema.any())), + meta: schema.recordOf(schema.string(), schema.any()), + $state: schema.maybe( + schema.object({ + store: schema.oneOf([ + schema.literal(filterStateStore.APP_STATE), + schema.literal(filterStateStore.GLOBAL_STATE), + ]), + }) + ), + }) + ), + dsl: schema.maybe(schema.string()), +}); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts index f10eb420963e..a715bd13f2f7 100644 --- a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/create/schemas/v1.ts @@ -8,10 +8,12 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowCategoryIdsSchemaV1 } from '../../../shared'; import { rRuleRequestSchemaV1 } from '../../../../r_rule'; +import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; export const createBodySchema = schema.object({ title: schema.string(), duration: schema.number(), r_rule: rRuleRequestSchemaV1, category_ids: maintenanceWindowCategoryIdsSchemaV1, + scoped_query: schema.maybe(schema.nullable(alertsFilterQuerySchemaV1)), }); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts index 970cd3442457..ac61048d760a 100644 --- a/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/apis/update/schemas/v1.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowCategoryIdsSchemaV1 } from '../../../shared'; import { rRuleRequestSchemaV1 } from '../../../../r_rule'; +import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; export const updateParamsSchema = schema.object({ id: schema.string(), @@ -19,4 +20,5 @@ export const updateBodySchema = schema.object({ duration: schema.maybe(schema.number()), r_rule: schema.maybe(rRuleRequestSchemaV1), category_ids: maintenanceWindowCategoryIdsSchemaV1, + scoped_query: schema.maybe(schema.nullable(alertsFilterQuerySchemaV1)), }); diff --git a/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts index 410a1dc1e439..648b2b806978 100644 --- a/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/maintenance_window/response/schemas/v1.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowStatusV1 } from '..'; import { maintenanceWindowCategoryIdsSchemaV1 } from '../../shared'; import { rRuleResponseSchemaV1 } from '../../../r_rule'; +import { alertsFilterQuerySchemaV1 } from '../../../alerts_filter_query'; export const maintenanceWindowEventSchema = schema.object({ gte: schema.string(), @@ -36,4 +37,5 @@ export const maintenanceWindowResponseSchema = schema.object({ schema.literal(maintenanceWindowStatusV1.ARCHIVED), ]), category_ids: maintenanceWindowCategoryIdsSchemaV1, + scoped_query: schema.maybe(schema.nullable(alertsFilterQuerySchemaV1)), }); diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts index 751f2e8c3878..30a294d5c052 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; import { notifyWhenSchemaV1 } from '../../../response'; -import { filterStateStore } from '../../../common/constants/v1'; +import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; export const actionFrequencySchema = schema.object({ summary: schema.boolean(), @@ -17,26 +17,7 @@ export const actionFrequencySchema = schema.object({ }); export const actionAlertsFilterSchema = schema.object({ - query: schema.maybe( - schema.object({ - kql: schema.string(), - filters: schema.arrayOf( - schema.object({ - query: schema.maybe(schema.recordOf(schema.string(), schema.any())), - meta: schema.recordOf(schema.string(), schema.any()), - $state: schema.maybe( - schema.object({ - store: schema.oneOf([ - schema.literal(filterStateStore.APP_STATE), - schema.literal(filterStateStore.GLOBAL_STATE), - ]), - }) - ), - }) - ), - dsl: schema.maybe(schema.string()), - }) - ), + query: schema.maybe(alertsFilterQuerySchemaV1), timeframe: schema.maybe( schema.object({ days: schema.arrayOf( diff --git a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts index 0e043aa21766..1c7b202f5906 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts @@ -7,13 +7,13 @@ import { schema } from '@kbn/config-schema'; import { rRuleResponseSchemaV1 } from '../../../r_rule'; +import { alertsFilterQuerySchemaV1 } from '../../../alerts_filter_query'; import { ruleNotifyWhen as ruleNotifyWhenV1, ruleExecutionStatusValues as ruleExecutionStatusValuesV1, ruleExecutionStatusErrorReason as ruleExecutionStatusErrorReasonV1, ruleExecutionStatusWarningReason as ruleExecutionStatusWarningReasonV1, ruleLastRunOutcomeValues as ruleLastRunOutcomeValuesV1, - filterStateStore as filterStateStoreV1, } from '../../common/constants/v1'; import { validateNotifyWhenV1 } from '../../validation'; @@ -41,25 +41,7 @@ const actionFrequencySchema = schema.object({ }); const actionAlertsFilterSchema = schema.object({ - query: schema.maybe( - schema.object({ - kql: schema.string(), - filters: schema.arrayOf( - schema.object({ - query: schema.maybe(schema.recordOf(schema.string(), schema.any())), - meta: schema.recordOf(schema.string(), schema.any()), - $state: schema.maybe( - schema.object({ - store: schema.oneOf([ - schema.literal(filterStateStoreV1.APP_STATE), - schema.literal(filterStateStoreV1.GLOBAL_STATE), - ]), - }) - ), - }) - ), - }) - ), + query: schema.maybe(alertsFilterQuerySchemaV1), timeframe: schema.maybe( schema.object({ days: schema.arrayOf( diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.json b/x-pack/plugins/alerting/docs/openapi/bundled.json index 6e09c658ae40..0ffb3afc1118 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.json +++ b/x-pack/plugins/alerting/docs/openapi/bundled.json @@ -1,9 +1,9 @@ { - "openapi": "3.0.1", + "openapi": "3.1.0", "info": { "title": "Alerting", "description": "OpenAPI schema for alerting endpoints", - "version": "0.1", + "version": "0.2", "contact": { "name": "Alerting Team" }, @@ -239,7 +239,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } } ], @@ -496,9 +498,11 @@ "description": "The default operator to use for the simple_query_string.", "schema": { "type": "string", - "default": "OR" - }, - "example": "OR" + "default": "OR", + "examples": [ + "OR" + ] + } }, { "name": "fields", @@ -541,9 +545,11 @@ "description": "The page number to return.", "schema": { "type": "integer", - "default": 1 - }, - "example": 1 + "default": 1, + "examples": [ + 1 + ] + } }, { "name": "per_page", @@ -551,9 +557,11 @@ "description": "The number of rules to return per page.", "schema": { "type": "integer", - "default": 20 - }, - "example": 20 + "default": 20, + "examples": [ + 20 + ] + } }, { "name": "search", @@ -599,9 +607,11 @@ "asc", "desc" ], - "default": "desc" - }, - "example": "asc" + "default": "desc", + "examples": [ + "asc" + ] + } } ], "responses": { @@ -684,7 +694,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -694,7 +706,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } }, @@ -704,7 +718,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -714,7 +730,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } }, @@ -724,7 +742,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -734,7 +754,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } } @@ -743,12 +765,16 @@ "has_permanent_encryption_key": { "type": "boolean", "description": "If `false`, the encrypted saved object plugin does not have a permanent encryption key.", - "example": true + "examples": [ + true + ] }, "is_sufficiently_secure": { "type": "boolean", "description": "If `false`, security is enabled but TLS is not.", - "example": true + "examples": [ + true + ] } } }, @@ -1030,7 +1056,9 @@ "minimum_license_required": { "description": "The subscriptions required to use the rule type.", "type": "string", - "example": "basic" + "examples": [ + "basic" + ] }, "name": { "description": "The descriptive name of the rule type.", @@ -1039,7 +1067,9 @@ "producer": { "description": "An identifier for the application that produces this rule type.", "type": "string", - "example": "stackAlerts" + "examples": [ + "stackAlerts" + ] }, "recovery_action_group": { "description": "An action group to use when an alert goes from an active state to an inactive one.", @@ -1055,7 +1085,9 @@ }, "rule_task_timeout": { "type": "string", - "example": "5m" + "examples": [ + "5m" + ] } } } @@ -1290,7 +1322,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1329,7 +1363,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1375,7 +1411,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } }, { @@ -1464,7 +1502,9 @@ "interval": { "type": "string", "description": "The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute.", - "example": "10s" + "examples": [ + "10s" + ] } } }, @@ -1529,7 +1569,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1601,7 +1643,9 @@ "interval": { "type": "string", "description": "The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute.", - "example": "1d" + "examples": [ + "1d" + ] } } }, @@ -1668,7 +1712,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1712,7 +1758,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1756,7 +1804,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1800,7 +1850,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } } ], @@ -1840,9 +1892,11 @@ "description": "The default operator to use for the `simple_query_string`.", "schema": { "type": "string", - "default": "OR" - }, - "example": "OR" + "default": "OR", + "examples": [ + "OR" + ] + } }, { "name": "fields", @@ -1885,9 +1939,11 @@ "description": "The page number to return.", "schema": { "type": "integer", - "default": 1 - }, - "example": 1 + "default": 1, + "examples": [ + 1 + ] + } }, { "name": "per_page", @@ -1895,9 +1951,11 @@ "description": "The number of alerts to return per page.", "schema": { "type": "integer", - "default": 20 - }, - "example": 20 + "default": 20, + "examples": [ + 20 + ] + } }, { "name": "search", @@ -1943,9 +2001,11 @@ "asc", "desc" ], - "default": "desc" - }, - "example": "asc" + "default": "desc", + "examples": [ + "asc" + ] + } } ], "responses": { @@ -2021,7 +2081,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -2031,7 +2093,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } }, @@ -2041,7 +2105,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -2051,7 +2117,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } }, @@ -2061,7 +2129,9 @@ "properties": { "status": { "type": "string", - "example": "ok", + "examples": [ + "ok" + ], "enum": [ "error", "ok", @@ -2071,7 +2141,9 @@ "timestamp": { "type": "string", "format": "date-time", - "example": "2023-01-13T01:28:00.280Z" + "examples": [ + "2023-01-13T01:28:00.280Z" + ] } } } @@ -2080,12 +2152,16 @@ "hasPermanentEncryptionKey": { "type": "boolean", "description": "If `false`, the encrypted saved object plugin does not have a permanent encryption key.", - "example": true + "examples": [ + true + ] }, "isSufficientlySecure": { "type": "boolean", "description": "If `false`, security is enabled but TLS is not.", - "example": true + "examples": [ + true + ] } } } @@ -2278,7 +2354,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } }, { @@ -2288,7 +2366,9 @@ "required": true, "schema": { "type": "string", - "example": "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2" + "examples": [ + "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2" + ] } } ], @@ -2332,7 +2412,9 @@ "required": true, "schema": { "type": "string", - "example": "41893910-6bca-11eb-9e0d-85d233e3ee35" + "examples": [ + "41893910-6bca-11eb-9e0d-85d233e3ee35" + ] } }, { @@ -2342,7 +2424,9 @@ "required": true, "schema": { "type": "string", - "example": "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2" + "examples": [ + "dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2" + ] } } ], @@ -2373,7 +2457,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "parameters": { @@ -2393,7 +2478,9 @@ "required": true, "schema": { "type": "string", - "example": "default" + "examples": [ + "default" + ] } }, "rule_id": { @@ -2403,7 +2490,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } }, "alert_id": { @@ -2413,7 +2502,9 @@ "required": true, "schema": { "type": "string", - "example": "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + "examples": [ + "ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74" + ] } } }, @@ -2426,8 +2517,10 @@ "type": "object", "properties": { "alias": { - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "controlledBy": { "type": "string" @@ -2480,19 +2573,27 @@ "onActiveAlert", "onThrottleInterval" ], - "example": "onActiveAlert" + "examples": [ + "onActiveAlert" + ] }, "throttle": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if `notify_when` is set to `onThrottleInterval`. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values.\n", - "nullable": true, "default": null, - "example": "10m" + "examples": [ + "10m" + ] }, "actions": { - "type": "array", + "type": [ + "array", + "null" + ], "default": [], - "nullable": true, "items": { "type": "object", "required": [ @@ -2532,12 +2633,14 @@ "items": { "type": "integer" }, - "example": [ - 1, - 2, - 3, - 4, - 5 + "examples": [ + [ + 1, + 2, + 3, + 4, + 5 + ] ] }, "hours": { @@ -2547,19 +2650,25 @@ "end": { "type": "string", "description": "The end of the time frame in 24-hour notation (`hh:mm`).", - "example": "17:00" + "examples": [ + "17:00" + ] }, "start": { "type": "string", "description": "The start of the time frame in 24-hour notation (`hh:mm`).", - "example": "08:00" + "examples": [ + "08:00" + ] } } }, "timezone": { "type": "string", "description": "The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended.\n", - "example": "Europe/Madrid" + "examples": [ + "Europe/Madrid" + ] } } } @@ -2568,7 +2677,9 @@ "connector_type_id": { "type": "string", "description": "The type of connector. This property appears in responses but cannot be set in requests.", - "example": ".server-log", + "examples": [ + ".server-log" + ], "readOnly": true }, "frequency": { @@ -2594,12 +2705,16 @@ "group": { "type": "string", "description": "The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`.\n", - "example": "default" + "examples": [ + "default" + ] }, "id": { "type": "string", "description": "The identifier for the connector saved object.", - "example": "9dca3e00-74f5-11ed-9801-35303b735aef" + "examples": [ + "9dca3e00-74f5-11ed-9801-35303b735aef" + ] }, "params": { "type": "object", @@ -2609,7 +2724,9 @@ "uuid": { "type": "string", "description": "A universally unique identifier (UUID) for the action.", - "example": "1c7a1280-f28c-4e06-96b2-e4e5f05d1d61" + "examples": [ + "1c7a1280-f28c-4e06-96b2-e4e5f05d1d61" + ] } } } @@ -2632,7 +2749,9 @@ "properties": { "interval": { "type": "string", - "example": "1m" + "examples": [ + "1m" + ] } } }, @@ -3210,7 +3329,9 @@ "timewindowsize": { "description": "The size of the time window (in `timeWindowUnit` units), which determines how far back to search for documents. Generally it should be a value higher than the rule check interval to avoid gaps in detection.\n", "type": "integer", - "example": 5 + "examples": [ + 5 + ] }, "timewindowunit": { "description": "The type of units for the time window: seconds, minutes, hours, or days.\n", @@ -3221,7 +3342,9 @@ "h", "d" ], - "example": "m" + "examples": [ + "m" + ] }, "size": { "description": "The number of documents to pass to the configured actions when the threshold condition is met.\n", @@ -3247,7 +3370,9 @@ "type": "array", "items": { "type": "integer", - "example": 4000 + "examples": [ + 4000 + ] } }, "thresholdcomparator": { @@ -3261,7 +3386,9 @@ "between", "notBetween" ], - "example": ">" + "examples": [ + ">" + ] }, "params_es_query_rule": { "oneOf": [ @@ -3309,12 +3436,16 @@ "enum": [ "esqlQuery" ], - "example": "esqlQuery" + "examples": [ + "esqlQuery" + ] }, "size": { "type": "integer", "description": "When `searchType` is `esqlQuery`, this property is required but it does not affect the rule behavior.\n", - "example": 0 + "examples": [ + 0 + ] }, "termSize": { "$ref": "#/components/schemas/termsize" @@ -3334,7 +3465,9 @@ "enum": [ ">" ], - "example": ">" + "examples": [ + ">" + ] }, "timeField": { "$ref": "#/components/schemas/timefield" @@ -3400,7 +3533,9 @@ "properties": { "language": { "type": "string", - "example": "kuery" + "examples": [ + "kuery" + ] }, "query": { "type": "string" @@ -3415,7 +3550,9 @@ "enum": [ "searchSource" ], - "example": "searchSource" + "examples": [ + "searchSource" + ] }, "size": { "$ref": "#/components/schemas/size" @@ -3493,7 +3630,9 @@ "esQuery" ], "default": "esQuery", - "example": "esQuery" + "examples": [ + "esQuery" + ] }, "size": { "$ref": "#/components/schemas/size" @@ -6318,58 +6457,82 @@ "api_key_created_by_user": { "type": "boolean", "description": "Indicates whether the API key that is associated with the rule was created by the user.", - "example": false + "examples": [ + false + ] }, "api_key_owner": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "The owner of the API key that is associated with the rule and used to run background tasks.\n", - "nullable": true, - "example": "elastic" + "examples": [ + "elastic" + ] }, "consumer": { "type": "string", "description": "The application or feature that owns the rule. For example, `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`.", - "example": "alerts" + "examples": [ + "alerts" + ] }, "created_at": { "type": "string", "description": "The date and time that the rule was created.", "format": "date-time", - "example": "2022-12-05T23:36:58.284Z" + "examples": [ + "2022-12-05T23:36:58.284Z" + ] }, "created_by": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "The identifier for the user that created the rule.", - "nullable": true, - "example": "elastic" + "examples": [ + "elastic" + ] }, "enabled": { "type": "boolean", "description": "Indicates whether the rule is currently enabled.", - "example": true + "examples": [ + true + ] }, "execution_status": { "type": "object", "properties": { "last_duration": { "type": "integer", - "example": 55 + "examples": [ + 55 + ] }, "last_execution_date": { "type": "string", "format": "date-time", - "example": "2022-12-06T00:13:43.890Z" + "examples": [ + "2022-12-06T00:13:43.890Z" + ] }, "status": { "type": "string", - "example": "ok" + "examples": [ + "ok" + ] } } }, "id": { "type": "string", "description": "The identifier for the rule.", - "example": "b530fed0-74f5-11ed-9801-35303b735aef" + "examples": [ + "b530fed0-74f5-11ed-9801-35303b735aef" + ] }, "last_run": { "type": "object", @@ -6393,51 +6556,71 @@ }, "outcome": { "type": "string", - "example": "succeeded" + "examples": [ + "succeeded" + ] }, "outcome_msg": { - "type": "array", + "type": [ + "array", + "null" + ], "items": { "type": "string" - }, - "nullable": true + } }, "outcome_order": { "type": "integer" }, "warning": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] } } }, "muted_alert_ids": { - "type": "array", - "nullable": true, + "type": [ + "array", + "null" + ], "items": { "type": "string" } }, "mute_all": { "type": "boolean", - "example": false + "examples": [ + false + ] }, "name": { "type": "string", "description": "The name of the rule.", - "example": "cluster_health_rule" + "examples": [ + "cluster_health_rule" + ] }, "next_run": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-12-06T00:14:43.818Z" + "examples": [ + "2022-12-06T00:14:43.818Z" + ] }, "notify_when": { - "type": "string", - "description": "Indicates how often alerts generate actions.", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "Indicates how often alerts generate actions." }, "params": { "type": "object", @@ -6451,7 +6634,9 @@ "rule_type_id": { "type": "string", "description": "The identifier for the type of rule. For example, `.es-query`, `.index-threshold`, `logs.alert.document.count`, `monitoring_alert_cluster_health`, `siem.thresholdRule`, or `xpack.ml.anomaly_detection_alert`.\n", - "example": "monitoring_alert_cluster_health" + "examples": [ + "monitoring_alert_cluster_health" + ] }, "running": { "type": "boolean", @@ -6462,7 +6647,9 @@ }, "scheduled_task_id": { "type": "string", - "example": "b530fed0-74f5-11ed-9801-35303b735aef" + "examples": [ + "b530fed0-74f5-11ed-9801-35303b735aef" + ] }, "tags": { "$ref": "#/components/schemas/tags" @@ -6473,13 +6660,19 @@ "updated_at": { "type": "string", "description": "The date and time that the rule was updated most recently.", - "example": "2022-12-05T23:36:58.284Z" + "examples": [ + "2022-12-05T23:36:58.284Z" + ] }, "updated_by": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "The identifier for the user that updated this rule most recently.", - "nullable": true, - "example": "elastic" + "examples": [ + "elastic" + ] } } }, @@ -6489,7 +6682,9 @@ "properties": { "error": { "type": "string", - "example": "Unauthorized", + "examples": [ + "Unauthorized" + ], "enum": [ "Unauthorized" ] @@ -6499,7 +6694,9 @@ }, "statusCode": { "type": "integer", - "example": 401, + "examples": [ + 401 + ], "enum": [ 401 ] @@ -6511,18 +6708,24 @@ "properties": { "error": { "type": "string", - "example": "Not Found", + "examples": [ + "Not Found" + ], "enum": [ "Not Found" ] }, "message": { "type": "string", - "example": "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + "examples": [ + "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + ] }, "statusCode": { "type": "integer", - "example": 404, + "examples": [ + 404 + ], "enum": [ 404 ] @@ -6545,7 +6748,9 @@ "name": { "type": "string", "description": "The name of the rule.", - "example": "cluster_health_rule" + "examples": [ + "cluster_health_rule" + ] }, "notify_when": { "$ref": "#/components/schemas/notify_when" @@ -6604,28 +6809,40 @@ }, "alertTypeId": { "type": "string", - "example": ".index-threshold" + "examples": [ + ".index-threshold" + ] }, "apiKeyOwner": { - "type": "string", - "nullable": true, - "example": "elastic" + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] }, "createdAt": { "type": "string", "description": "The date and time that the alert was created.", "format": "date-time", - "example": "2022-12-05T23:36:58.284Z" + "examples": [ + "2022-12-05T23:36:58.284Z" + ] }, "createdBy": { "type": "string", "description": "The identifier for the user that created the alert.", - "example": "elastic" + "examples": [ + "elastic" + ] }, "enabled": { "type": "boolean", "description": "Indicates whether the alert is currently enabled.", - "example": true + "examples": [ + true + ] }, "executionStatus": { "type": "object", @@ -6633,26 +6850,36 @@ "lastExecutionDate": { "type": "string", "format": "date-time", - "example": "2022-12-06T00:13:43.890Z" + "examples": [ + "2022-12-06T00:13:43.890Z" + ] }, "status": { "type": "string", - "example": "ok" + "examples": [ + "ok" + ] } } }, "id": { "type": "string", "description": "The identifier for the alert.", - "example": "b530fed0-74f5-11ed-9801-35303b735aef" + "examples": [ + "b530fed0-74f5-11ed-9801-35303b735aef" + ] }, "muteAll": { "type": "boolean", - "example": false + "examples": [ + false + ] }, "mutedInstanceIds": { - "type": "array", - "nullable": true, + "type": [ + "array", + "null" + ], "items": { "type": "string" } @@ -6660,11 +6887,15 @@ "name": { "type": "string", "description": "The name of the alert.", - "example": "my alert" + "examples": [ + "my alert" + ] }, "notifyWhen": { "type": "string", - "example": "onActionGroupChange" + "examples": [ + "onActionGroupChange" + ] }, "params": { "type": "object", @@ -6680,7 +6911,9 @@ }, "scheduledTaskId": { "type": "string", - "example": "b530fed0-74f5-11ed-9801-35303b735aef" + "examples": [ + "b530fed0-74f5-11ed-9801-35303b735aef" + ] }, "tags": { "type": "array", @@ -6689,18 +6922,26 @@ } }, "throttle": { - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "updatedAt": { "type": "string", - "example": "2022-12-05T23:36:58.284Z" + "examples": [ + "2022-12-05T23:36:58.284Z" + ] }, "updatedBy": { - "type": "string", + "type": [ + "string", + "null" + ], "description": "The identifier for the user that updated this alert most recently.", - "nullable": true, - "example": "elastic" + "examples": [ + "elastic" + ] } } } diff --git a/x-pack/plugins/alerting/docs/openapi/bundled.yaml b/x-pack/plugins/alerting/docs/openapi/bundled.yaml index 424326e12c8f..4a736e68e9b6 100644 --- a/x-pack/plugins/alerting/docs/openapi/bundled.yaml +++ b/x-pack/plugins/alerting/docs/openapi/bundled.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Alerting description: OpenAPI schema for alerting endpoints - version: '0.1' + version: '0.2' contact: name: Alerting Team license: @@ -147,7 +147,8 @@ paths: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: @@ -303,7 +304,8 @@ paths: schema: type: string default: OR - example: OR + examples: + - OR - name: fields in: query description: The fields to return in the `attributes` key of the response. @@ -333,14 +335,16 @@ paths: schema: type: integer default: 1 - example: 1 + examples: + - 1 - name: per_page in: query description: The number of rules to return per page. schema: type: integer default: 20 - example: 20 + examples: + - 20 - name: search in: query description: An Elasticsearch simple_query_string query that filters the objects in the response. @@ -370,7 +374,8 @@ paths: - asc - desc default: desc - example: asc + examples: + - asc responses: '200': description: Indicates a successful call. @@ -429,7 +434,8 @@ paths: properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -437,14 +443,16 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' execution_health: type: object description: The timestamp and status of the rule run. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -452,14 +460,16 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' read_health: type: object description: The timestamp and status of the rule reading events. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -467,15 +477,18 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' has_permanent_encryption_key: type: boolean description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. - example: true + examples: + - true is_sufficiently_secure: type: boolean description: If `false`, security is enabled but TLS is not. - example: true + examples: + - true examples: getAlertingHealthResponse: $ref: '#/components/examples/get_health_response' @@ -662,14 +675,16 @@ paths: minimum_license_required: description: The subscriptions required to use the rule type. type: string - example: basic + examples: + - basic name: description: The descriptive name of the rule type. type: string producer: description: An identifier for the application that produces this rule type. type: string - example: stackAlerts + examples: + - stackAlerts recovery_action_group: description: An action group to use when an alert goes from an active state to an inactive one. type: object @@ -680,7 +695,8 @@ paths: type: string rule_task_timeout: type: string - example: 5m + examples: + - 5m examples: getRuleTypesResponse: $ref: '#/components/examples/get_rule_types_response' @@ -814,7 +830,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -839,7 +856,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '200': description: Indicates a successful call. @@ -868,7 +886,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - $ref: '#/components/parameters/space_id' requestBody: required: true @@ -939,7 +958,8 @@ paths: interval: type: string description: The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute. - example: 10s + examples: + - 10s tags: type: array items: @@ -978,7 +998,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 requestBody: required: true content: @@ -1037,7 +1058,8 @@ paths: interval: type: string description: The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute. - example: 1d + examples: + - 1d tags: type: array items: @@ -1077,7 +1099,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -1104,7 +1127,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -1131,7 +1155,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -1158,7 +1183,8 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -1185,7 +1211,8 @@ paths: schema: type: string default: OR - example: OR + examples: + - OR - name: fields in: query description: The fields to return in the `attributes` key of the response. @@ -1215,14 +1242,16 @@ paths: schema: type: integer default: 1 - example: 1 + examples: + - 1 - name: per_page in: query description: The number of alerts to return per page. schema: type: integer default: 20 - example: 20 + examples: + - 20 - name: search in: query description: An Elasticsearch `simple_query_string` query that filters the alerts in the response. @@ -1252,7 +1281,8 @@ paths: - asc - desc default: desc - example: asc + examples: + - asc responses: '200': description: Indicates a successful call. @@ -1306,7 +1336,8 @@ paths: properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -1314,14 +1345,16 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' executionHealth: type: object description: The timestamp and status of the alert execution. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -1329,14 +1362,16 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' readHealth: type: object description: The timestamp and status of the alert reading events. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -1344,15 +1379,18 @@ paths: timestamp: type: string format: date-time - example: '2023-01-13T01:28:00.280Z' + examples: + - '2023-01-13T01:28:00.280Z' hasPermanentEncryptionKey: type: boolean description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. - example: true + examples: + - true isSufficientlySecure: type: boolean description: If `false`, security is enabled but TLS is not. - example: true + examples: + - true '401': description: Authorization information is missing or invalid. content: @@ -1478,14 +1516,16 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - in: path name: alertInstanceId description: An identifier for the alert instance. required: true schema: type: string - example: dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 + examples: + - dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 responses: '204': description: Indicates a successful call. @@ -1512,14 +1552,16 @@ paths: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - in: path name: alertInstanceId description: An identifier for the alert instance. required: true schema: type: string - example: dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 + examples: + - dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 responses: '204': description: Indicates a successful call. @@ -1537,7 +1579,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' parameters: kbn_xsrf: schema: @@ -1553,7 +1596,8 @@ components: required: true schema: type: string - example: default + examples: + - default rule_id: in: path name: ruleId @@ -1561,7 +1605,8 @@ components: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 alert_id: in: path name: alertId @@ -1569,7 +1614,8 @@ components: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 schemas: filter: type: object @@ -1579,8 +1625,9 @@ components: type: object properties: alias: - type: string - nullable: true + type: + - string + - 'null' controlledBy: type: string disabled: @@ -1615,18 +1662,22 @@ components: - onActionGroupChange - onActiveAlert - onThrottleInterval - example: onActiveAlert + examples: + - onActiveAlert throttle: - type: string + type: + - string + - 'null' description: | The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if `notify_when` is set to `onThrottleInterval`. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values. - nullable: true default: null - example: 10m + examples: + - 10m actions: - type: array + type: + - array + - 'null' default: [] - nullable: true items: type: object required: @@ -1661,12 +1712,12 @@ components: description: Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week. items: type: integer - example: - - 1 - - 2 - - 3 - - 4 - - 5 + examples: + - - 1 + - 2 + - 3 + - 4 + - 5 hours: type: object description: | @@ -1675,20 +1726,24 @@ components: end: type: string description: The end of the time frame in 24-hour notation (`hh:mm`). - example: '17:00' + examples: + - '17:00' start: type: string description: The start of the time frame in 24-hour notation (`hh:mm`). - example: '08:00' + examples: + - '08:00' timezone: type: string description: | The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended. - example: Europe/Madrid + examples: + - Europe/Madrid connector_type_id: type: string description: The type of connector. This property appears in responses but cannot be set in requests. - example: .server-log + examples: + - .server-log readOnly: true frequency: type: object @@ -1709,11 +1764,13 @@ components: type: string description: | The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`. - example: default + examples: + - default id: type: string description: The identifier for the connector saved object. - example: 9dca3e00-74f5-11ed-9801-35303b735aef + examples: + - 9dca3e00-74f5-11ed-9801-35303b735aef params: type: object description: The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context. @@ -1721,7 +1778,8 @@ components: uuid: type: string description: A universally unique identifier (UUID) for the action. - example: 1c7a1280-f28c-4e06-96b2-e4e5f05d1d61 + examples: + - 1c7a1280-f28c-4e06-96b2-e4e5f05d1d61 consumer: type: string description: | @@ -1739,7 +1797,8 @@ components: properties: interval: type: string - example: 1m + examples: + - 1m tags: type: array description: The tags for the rule. @@ -2170,7 +2229,8 @@ components: description: | The size of the time window (in `timeWindowUnit` units), which determines how far back to search for documents. Generally it should be a value higher than the rule check interval to avoid gaps in detection. type: integer - example: 5 + examples: + - 5 timewindowunit: description: | The type of units for the time window: seconds, minutes, hours, or days. @@ -2180,7 +2240,8 @@ components: - m - h - d - example: m + examples: + - m size: description: | The number of documents to pass to the configured actions when the threshold condition is met. @@ -2200,7 +2261,8 @@ components: type: array items: type: integer - example: 4000 + examples: + - 4000 thresholdcomparator: description: The comparison function for the threshold. For example, "is above", "is above or equals", "is below", "is below or equals", "is between", and "is not between". type: string @@ -2211,7 +2273,8 @@ components: - <= - between - notBetween - example: '>' + examples: + - '>' params_es_query_rule: oneOf: - type: object @@ -2248,12 +2311,14 @@ components: type: string enum: - esqlQuery - example: esqlQuery + examples: + - esqlQuery size: type: integer description: | When `searchType` is `esqlQuery`, this property is required but it does not affect the rule behavior. - example: 0 + examples: + - 0 termSize: $ref: '#/components/schemas/termsize' threshold: @@ -2270,7 +2335,8 @@ components: The comparison function for the threshold. When `searchType` is `esqlQuery`, this property is required and must be set to ">". Since the `threshold` value must be `0`, the result is that an alert occurs whenever the query returns results. enum: - '>' - example: '>' + examples: + - '>' timeField: $ref: '#/components/schemas/timefield' timeWindowSize: @@ -2315,7 +2381,8 @@ components: properties: language: type: string - example: kuery + examples: + - kuery query: type: string searchType: @@ -2323,7 +2390,8 @@ components: type: string enum: - searchSource - example: searchSource + examples: + - searchSource size: $ref: '#/components/schemas/size' termField: @@ -2375,7 +2443,8 @@ components: enum: - esQuery default: esQuery - example: esQuery + examples: + - esQuery size: $ref: '#/components/schemas/size' termField: @@ -4357,48 +4426,60 @@ components: api_key_created_by_user: type: boolean description: Indicates whether the API key that is associated with the rule was created by the user. - example: false + examples: + - false api_key_owner: - type: string + type: + - string + - 'null' description: | The owner of the API key that is associated with the rule and used to run background tasks. - nullable: true - example: elastic + examples: + - elastic consumer: type: string description: The application or feature that owns the rule. For example, `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`. - example: alerts + examples: + - alerts created_at: type: string description: The date and time that the rule was created. format: date-time - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' created_by: - type: string + type: + - string + - 'null' description: The identifier for the user that created the rule. - nullable: true - example: elastic + examples: + - elastic enabled: type: boolean description: Indicates whether the rule is currently enabled. - example: true + examples: + - true execution_status: type: object properties: last_duration: type: integer - example: 55 + examples: + - 55 last_execution_date: type: string format: date-time - example: '2022-12-06T00:13:43.890Z' + examples: + - '2022-12-06T00:13:43.890Z' status: type: string - example: ok + examples: + - ok id: type: string description: The identifier for the rule. - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef last_run: type: object properties: @@ -4415,39 +4496,49 @@ components: type: integer outcome: type: string - example: succeeded + examples: + - succeeded outcome_msg: - type: array + type: + - array + - 'null' items: type: string - nullable: true outcome_order: type: integer warning: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null muted_alert_ids: - type: array - nullable: true + type: + - array + - 'null' items: type: string mute_all: type: boolean - example: false + examples: + - false name: type: string description: The name of the rule. - example: cluster_health_rule + examples: + - cluster_health_rule next_run: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-12-06T00:14:43.818Z' + examples: + - '2022-12-06T00:14:43.818Z' notify_when: - type: string + type: + - string + - 'null' description: Indicates how often alerts generate actions. - nullable: true params: type: object description: The parameters for the rule. @@ -4459,7 +4550,8 @@ components: type: string description: | The identifier for the type of rule. For example, `.es-query`, `.index-threshold`, `logs.alert.document.count`, `monitoring_alert_cluster_health`, `siem.thresholdRule`, or `xpack.ml.anomaly_detection_alert`. - example: monitoring_alert_cluster_health + examples: + - monitoring_alert_cluster_health running: type: boolean description: Indicates whether the rule is running. @@ -4467,7 +4559,8 @@ components: $ref: '#/components/schemas/schedule' scheduled_task_id: type: string - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef tags: $ref: '#/components/schemas/tags' throttle: @@ -4475,26 +4568,31 @@ components: updated_at: type: string description: The date and time that the rule was updated most recently. - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' updated_by: - type: string + type: + - string + - 'null' description: The identifier for the user that updated this rule most recently. - nullable: true - example: elastic + examples: + - elastic 401_response: type: object title: Unsuccessful rule API response properties: error: type: string - example: Unauthorized + examples: + - Unauthorized enum: - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 enum: - 401 404_response: @@ -4502,15 +4600,18 @@ components: properties: error: type: string - example: Not Found + examples: + - Not Found enum: - Not Found message: type: string - example: Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found + examples: + - Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found statusCode: type: integer - example: 404 + examples: + - 404 enum: - 404 update_rule_request: @@ -4528,7 +4629,8 @@ components: name: type: string description: The name of the rule. - example: cluster_health_rule + examples: + - cluster_health_rule notify_when: $ref: '#/components/schemas/notify_when' params: @@ -4569,53 +4671,66 @@ components: type: object alertTypeId: type: string - example: .index-threshold + examples: + - .index-threshold apiKeyOwner: - type: string - nullable: true - example: elastic + type: + - string + - 'null' + examples: + - elastic createdAt: type: string description: The date and time that the alert was created. format: date-time - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' createdBy: type: string description: The identifier for the user that created the alert. - example: elastic + examples: + - elastic enabled: type: boolean description: Indicates whether the alert is currently enabled. - example: true + examples: + - true executionStatus: type: object properties: lastExecutionDate: type: string format: date-time - example: '2022-12-06T00:13:43.890Z' + examples: + - '2022-12-06T00:13:43.890Z' status: type: string - example: ok + examples: + - ok id: type: string description: The identifier for the alert. - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef muteAll: type: boolean - example: false + examples: + - false mutedInstanceIds: - type: array - nullable: true + type: + - array + - 'null' items: type: string name: type: string description: The name of the alert. - example: my alert + examples: + - my alert notifyWhen: type: string - example: onActionGroupChange + examples: + - onActionGroupChange params: type: object additionalProperties: true @@ -4626,22 +4741,27 @@ components: type: string scheduledTaskId: type: string - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef tags: type: array items: type: string throttle: - type: string - nullable: true + type: + - string + - 'null' updatedAt: type: string - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' updatedBy: - type: string + type: + - string + - 'null' description: The identifier for the user that updated this alert most recently. - nullable: true - example: elastic + examples: + - elastic examples: create_es_query_esql_rule_request: summary: Create an Elasticsearch query rule that uses Elasticsearch Query Language (ES|QL). diff --git a/x-pack/plugins/alerting/docs/openapi/components/parameters/alert_id.yaml b/x-pack/plugins/alerting/docs/openapi/components/parameters/alert_id.yaml index 27427e1ec675..3ae77530b04d 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/parameters/alert_id.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/parameters/alert_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the alert. The identifier is generated by the rul required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 \ No newline at end of file + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/parameters/rule_id.yaml b/x-pack/plugins/alerting/docs/openapi/components/parameters/rule_id.yaml index 4b5d14e20735..18cadc0e5d7e 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/parameters/rule_id.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/parameters/rule_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the rule. required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 \ No newline at end of file + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/parameters/space_id.yaml b/x-pack/plugins/alerting/docs/openapi/components/parameters/space_id.yaml index 0a9fba457e3e..45787e844cae 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/parameters/space_id.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/parameters/space_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the space. If `/s/` and the identifier are omitte required: true schema: type: string - example: default + examples: + - default diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml index c6044998f864..ed5e2a823bc0 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/401_response.yaml @@ -3,13 +3,15 @@ title: Unsuccessful rule API response properties: error: type: string - example: Unauthorized + examples: + - Unauthorized enum: - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 enum: - 401 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml index 1b8a118703ec..875307d5a389 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/404_response.yaml @@ -2,14 +2,17 @@ type: object properties: error: type: string - example: Not Found + examples: + - Not Found enum: - Not Found message: type: string - example: "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" + examples: + - "Saved object [alert/caaad6d0-920c-11ed-b36a-874bd1548a00] not found" statusCode: type: integer - example: 404 + examples: + - 404 enum: - 404 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/actions.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/actions.yaml index ee11bead0135..4297900d7a95 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/actions.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/actions.yaml @@ -1,6 +1,7 @@ -type: array +type: + - "array" + - "null" default: [] -nullable: true items: type: object required: @@ -37,7 +38,8 @@ items: description: Defines the days of the week that the action can run, represented as an array of numbers. For example, `1` represents Monday. An empty array is equivalent to specifying all the days of the week. items: type: integer - example: [1,2,3,4,5] + examples: + - [1,2,3,4,5] hours: type: object description: > @@ -47,21 +49,25 @@ items: end: type: string description: The end of the time frame in 24-hour notation (`hh:mm`). - example: 17:00 + examples: + - 17:00 start: type: string description: The start of the time frame in 24-hour notation (`hh:mm`). - example: 08:00 + examples: + - 08:00 timezone: type: string description: > The ISO time zone for the `hours` values. Values such as `UTC` and `UTC+1` also work but lack built-in daylight savings time support and are not recommended. - example: Europe/Madrid + examples: + - Europe/Madrid connector_type_id: type: string description: The type of connector. This property appears in responses but cannot be set in requests. - example: .server-log + examples: + - .server-log readOnly: true frequency: type: object @@ -87,11 +93,13 @@ items: The group name, which affects when the action runs (for example, when the threshold is met or when the alert is recovered). Each rule type has a list of valid action group names. If you don't need to group actions, set to `default`. - example: default + examples: + - default id: type: string description: The identifier for the connector saved object. - example: 9dca3e00-74f5-11ed-9801-35303b735aef + examples: + - 9dca3e00-74f5-11ed-9801-35303b735aef params: type: object description: The parameters for the action, which are sent to the connector. The `params` are handled as Mustache templates and passed a default set of context. @@ -99,4 +107,5 @@ items: uuid: type: string description: A universally unique identifier (UUID) for the action. - example: 1c7a1280-f28c-4e06-96b2-e4e5f05d1d61 + examples: + - 1c7a1280-f28c-4e06-96b2-e4e5f05d1d61 diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/alert_response_properties.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/alert_response_properties.yaml index 06fa627311e7..744e4ead6c94 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/alert_response_properties.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/alert_response_properties.yaml @@ -7,53 +7,66 @@ properties: type: object alertTypeId: type: string - example: ".index-threshold" + examples: + - ".index-threshold" apiKeyOwner: - type: string - nullable: true - example: elastic + type: + - "string" + - "null" + examples: + - elastic createdAt: type: string description: The date and time that the alert was created. format: date-time - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' createdBy: type: string description: The identifier for the user that created the alert. - example: elastic + examples: + - elastic enabled: type: boolean description: Indicates whether the alert is currently enabled. - example: true + examples: + - true executionStatus: type: object properties: lastExecutionDate: type: string format: date-time - example: '2022-12-06T00:13:43.890Z' + examples: + - '2022-12-06T00:13:43.890Z' status: type: string - example: ok + examples: + - ok id: type: string description: The identifier for the alert. - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef muteAll: type: boolean - example: false + examples: + - false mutedInstanceIds: - type: array - nullable: true + type: + - "array" + - "null" items: type: string name: type: string description: The name of the alert. - example: my alert + examples: + - my alert notifyWhen: type: string - example: onActionGroupChange + examples: + - onActionGroupChange params: type: object additionalProperties: true @@ -64,19 +77,24 @@ properties: type: string scheduledTaskId: type: string - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef tags: type: array items: type: string throttle: - type: string - nullable: true + type: + - "string" + - "null" updatedAt: type: string - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' updatedBy: - type: string + type: + - "string" + - "null" description: The identifier for the user that updated this alert most recently. - nullable: true - example: elastic \ No newline at end of file + examples: + - elastic \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/filter.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/filter.yaml index cb6a77c21568..ba8507f87f05 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/filter.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/filter.yaml @@ -5,8 +5,9 @@ properties: type: object properties: alias: - type: string - nullable: true + type: + - "string" + - "null" controlledBy: type: string disabled: diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/notify_when.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/notify_when.yaml index 0dcd244fc33e..bb68967b6f5c 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/notify_when.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/notify_when.yaml @@ -8,4 +8,5 @@ enum: - onActionGroupChange - onActiveAlert - onThrottleInterval -example: onActiveAlert \ No newline at end of file +examples: + - onActiveAlert \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/params_es_query_rule.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/params_es_query_rule.yaml index 99b6a6f393a3..f51cbce979ab 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/params_es_query_rule.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/params_es_query_rule.yaml @@ -35,12 +35,14 @@ oneOf: type: string enum: - esqlQuery - example: esqlQuery + examples: + - esqlQuery size: type: integer description: > When `searchType` is `esqlQuery`, this property is required but it does not affect the rule behavior. - example: 0 + examples: + - 0 termSize: $ref: 'termsize.yaml' threshold: @@ -60,7 +62,8 @@ oneOf: Since the `threshold` value must be `0`, the result is that an alert occurs whenever the query returns results. enum: - ">" - example: ">" + examples: + - ">" timeField: $ref: 'timefield.yaml' timeWindowSize: @@ -105,7 +108,8 @@ oneOf: properties: language: type: string - example: kuery + examples: + - kuery query: type: string searchType: @@ -113,7 +117,8 @@ oneOf: type: string enum: - searchSource - example: searchSource + examples: + - searchSource size: $ref: 'size.yaml' termField: @@ -165,7 +170,8 @@ oneOf: enum: - esQuery default: esQuery - example: esQuery + examples: + - esQuery size: $ref: 'size.yaml' termField: diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/rule_response_properties.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/rule_response_properties.yaml index 13f62ba63e22..51310c87b6c5 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/rule_response_properties.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/rule_response_properties.yaml @@ -25,48 +25,60 @@ properties: api_key_created_by_user: type: boolean description: Indicates whether the API key that is associated with the rule was created by the user. - example: false + examples: + - false api_key_owner: - type: string + type: + - "string" + - "null" description: > The owner of the API key that is associated with the rule and used to run background tasks. - nullable: true - example: elastic + examples: + - elastic consumer: type: string description: The application or feature that owns the rule. For example, `alerts`, `apm`, `discover`, `infrastructure`, `logs`, `metrics`, `ml`, `monitoring`, `securitySolution`, `siem`, `stackAlerts`, or `uptime`. - example: alerts + examples: + - alerts created_at: type: string description: The date and time that the rule was created. format: date-time - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' created_by: - type: string + type: + - "string" + - "null" description: The identifier for the user that created the rule. - nullable: true - example: elastic + examples: + - elastic enabled: type: boolean description: Indicates whether the rule is currently enabled. - example: true + examples: + - true execution_status: type: object properties: last_duration: type: integer - example: 55 + examples: + - 55 last_execution_date: type: string format: date-time - example: '2022-12-06T00:13:43.890Z' + examples: + - '2022-12-06T00:13:43.890Z' status: type: string - example: ok + examples: + - ok id: type: string description: The identifier for the rule. - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef last_run: type: object properties: @@ -83,39 +95,49 @@ properties: type: integer outcome: type: string - example: succeeded + examples: + - succeeded outcome_msg: - type: array + type: + - "array" + - "null" items: type: string - nullable: true outcome_order: type: integer warning: - type: string - nullable: true - example: null + type: + - "string" + - "null" + examples: + - null muted_alert_ids: - type: array - nullable: true + type: + - "array" + - "null" items: type: string mute_all: type: boolean - example: false + examples: + - false name: type: string description: The name of the rule. - example: cluster_health_rule + examples: + - cluster_health_rule next_run: - type: string + type: + - "string" + - "null" format: date-time - nullable: true - example: '2022-12-06T00:14:43.818Z' + examples: + - '2022-12-06T00:14:43.818Z' notify_when: - type: string + type: + - "string" + - "null" description: Indicates how often alerts generate actions. - nullable: true params: type: object description: The parameters for the rule. @@ -127,7 +149,8 @@ properties: type: string description: > The identifier for the type of rule. For example, `.es-query`, `.index-threshold`, `logs.alert.document.count`, `monitoring_alert_cluster_health`, `siem.thresholdRule`, or `xpack.ml.anomaly_detection_alert`. - example: monitoring_alert_cluster_health + examples: + - monitoring_alert_cluster_health running: type: boolean description: Indicates whether the rule is running. @@ -135,7 +158,8 @@ properties: $ref: 'schedule.yaml' scheduled_task_id: type: string - example: b530fed0-74f5-11ed-9801-35303b735aef + examples: + - b530fed0-74f5-11ed-9801-35303b735aef tags: $ref: 'tags.yaml' throttle: @@ -143,9 +167,12 @@ properties: updated_at: type: string description: The date and time that the rule was updated most recently. - example: '2022-12-05T23:36:58.284Z' + examples: + - '2022-12-05T23:36:58.284Z' updated_by: - type: string + type: + - "string" + - "null" description: The identifier for the user that updated this rule most recently. - nullable: true - example: elastic \ No newline at end of file + examples: + - elastic \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/schedule.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/schedule.yaml index 57ddf84ceb41..75e98d9a8d19 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/schedule.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/schedule.yaml @@ -3,4 +3,5 @@ description: The check interval, which specifies how frequently the rule conditi properties: interval: type: string - example: 1m \ No newline at end of file + examples: + - 1m \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/threshold.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/threshold.yaml index 4d646f637522..7060ecf4e91a 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/threshold.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/threshold.yaml @@ -4,4 +4,5 @@ description: > type: array items: type: integer - example: 4000 \ No newline at end of file + examples: + - 4000 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/thresholdcomparator.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/thresholdcomparator.yaml index 3459365ee0a1..dd39d4c0bdc3 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/thresholdcomparator.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/thresholdcomparator.yaml @@ -7,4 +7,5 @@ enum: - "<=" - between - notBetween -example: ">" \ No newline at end of file +examples: + - ">" \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/throttle.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/throttle.yaml index 19d8e621cdaf..f45573dac8ab 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/throttle.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/throttle.yaml @@ -1,9 +1,11 @@ -type: string +type: + - "string" + - "null" description: > The throttle interval, which defines how often an alert generates repeated actions. It is specified in seconds, minutes, hours, or days and is applicable only if `notify_when` is set to `onThrottleInterval`. NOTE: You cannot specify the throttle interval at both the rule and action level. The recommended method is to set it for each action. If you set it at the rule level then update the rule in Kibana, it is automatically changed to use action-specific values. -nullable: true default: null -example: 10m \ No newline at end of file +examples: + - 10m \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowsize.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowsize.yaml index 7271f62f8dac..137ae56a9167 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowsize.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowsize.yaml @@ -2,4 +2,5 @@ description: > The size of the time window (in `timeWindowUnit` units), which determines how far back to search for documents. Generally it should be a value higher than the rule check interval to avoid gaps in detection. type: integer -example: 5 \ No newline at end of file +examples: + - 5 \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowunit.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowunit.yaml index c0f2d458ae0e..bc2cbf1bd3e1 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowunit.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/timewindowunit.yaml @@ -6,4 +6,5 @@ enum: - m - h - d -example: "m" \ No newline at end of file +examples: + - "m" \ No newline at end of file diff --git a/x-pack/plugins/alerting/docs/openapi/components/schemas/update_rule_request.yaml b/x-pack/plugins/alerting/docs/openapi/components/schemas/update_rule_request.yaml index 58b6049aa107..63293f76ca71 100644 --- a/x-pack/plugins/alerting/docs/openapi/components/schemas/update_rule_request.yaml +++ b/x-pack/plugins/alerting/docs/openapi/components/schemas/update_rule_request.yaml @@ -12,7 +12,8 @@ properties: name: type: string description: The name of the rule. - example: cluster_health_rule + examples: + - cluster_health_rule notify_when: $ref: 'notify_when.yaml' params: diff --git a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml index 5b3d70e78069..39c46ca8513f 100644 --- a/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/alerting/docs/openapi/entrypoint.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Alerting description: OpenAPI schema for alerting endpoints - version: '0.1' + version: '0.2' contact: name: Alerting Team license: @@ -68,7 +68,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml index 5b856e24ca99..25ae1cb0b9fc 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@_health.yaml @@ -28,7 +28,8 @@ get: properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -36,14 +37,16 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" execution_health: type: object description: The timestamp and status of the rule run. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -51,14 +54,16 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" read_health: type: object description: The timestamp and status of the rule reading events. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -66,15 +71,18 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" has_permanent_encryption_key: type: boolean description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. - example: true + examples: + - true is_sufficiently_secure: type: boolean description: If `false`, security is enabled but TLS is not. - example: true + examples: + - true examples: getAlertingHealthResponse: $ref: '../components/examples/get_health_response.yaml' diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml index a4d624110014..96c5973c570c 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule@{ruleid}.yaml @@ -90,7 +90,8 @@ post: required: true schema: type: string - example: ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 + examples: + - ac4e6b90-6be7-11eb-ba0d-9b1c1f912d74 requestBody: required: true content: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml index 1dba3e085e2b..41ec2aeadbe3 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rule_types.yaml @@ -186,14 +186,16 @@ get: minimum_license_required: description: The subscriptions required to use the rule type. type: string - example: basic + examples: + - basic name: description: The descriptive name of the rule type. type: string producer: description: An identifier for the application that produces this rule type. type: string - example: stackAlerts + examples: + - stackAlerts recovery_action_group: description: An action group to use when an alert goes from an active state to an inactive one. type: object @@ -204,7 +206,8 @@ get: type: string rule_task_timeout: type: string - example: 5m + examples: + - 5m examples: getRuleTypesResponse: $ref: '../components/examples/get_rule_types_response.yaml' diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml index f512a0660f18..8055b4b5310a 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerting@rules@_find.yaml @@ -19,7 +19,8 @@ get: schema: type: string default: OR - example: OR + examples: + - OR - name: fields in: query description: The fields to return in the `attributes` key of the response. @@ -53,14 +54,16 @@ get: schema: type: integer default: 1 - example: 1 + examples: + - 1 - name: per_page in: query description: The number of rules to return per page. schema: type: integer default: 20 - example: 20 + examples: + - 20 - name: search in: query description: An Elasticsearch simple_query_string query that filters the objects in the response. @@ -91,7 +94,8 @@ get: - asc - desc default: desc - example: asc + examples: + - asc responses: '200': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_find.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_find.yaml index 32dcbbf218a3..2cc8acdf5c5a 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_find.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_find.yaml @@ -17,7 +17,8 @@ get: schema: type: string default: OR - example: OR + examples: + - OR - name: fields in: query description: The fields to return in the `attributes` key of the response. @@ -51,14 +52,16 @@ get: schema: type: integer default: 1 - example: 1 + examples: + - 1 - name: per_page in: query description: The number of alerts to return per page. schema: type: integer default: 20 - example: 20 + examples: + - 20 - name: search in: query description: An Elasticsearch `simple_query_string` query that filters the alerts in the response. @@ -89,7 +92,8 @@ get: - asc - desc default: desc - example: asc + examples: + - asc responses: '200': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_health.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_health.yaml index eba22ac1b409..593977bd384d 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_health.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@_health.yaml @@ -26,7 +26,8 @@ get: properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -34,14 +35,16 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" executionHealth: type: object description: The timestamp and status of the alert execution. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -49,14 +52,16 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" readHealth: type: object description: The timestamp and status of the alert reading events. properties: status: type: string - example: ok + examples: + - ok enum: - error - ok @@ -64,15 +69,18 @@ get: timestamp: type: string format: date-time - example: "2023-01-13T01:28:00.280Z" + examples: + - "2023-01-13T01:28:00.280Z" hasPermanentEncryptionKey: type: boolean description: If `false`, the encrypted saved object plugin does not have a permanent encryption key. - example: true + examples: + - true isSufficientlySecure: type: boolean description: If `false`, security is enabled but TLS is not. - example: true + examples: + - true '401': description: Authorization information is missing or invalid. content: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}.yaml index 4af612fc150c..48a1b12984b4 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}.yaml @@ -16,7 +16,8 @@ delete: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. @@ -42,7 +43,8 @@ get: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '200': description: Indicates a successful call. @@ -72,7 +74,8 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - $ref: '../components/parameters/space_id.yaml' requestBody: required: true @@ -146,7 +149,8 @@ post: interval: type: string description: The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute. - example: "10s" + examples: + - "10s" tags: type: array items: @@ -189,7 +193,8 @@ put: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 requestBody: required: true content: @@ -251,7 +256,8 @@ put: interval: type: string description: The interval format specifies the interval in seconds, minutes, hours or days at which the alert should execute. - example: "1d" + examples: + - "1d" tags: type: array items: diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_disable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_disable.yaml index 62fc4de90cae..a383c71ed0ea 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_disable.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_disable.yaml @@ -14,7 +14,8 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_enable.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_enable.yaml index 85ede004c189..19b782ea3ccc 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_enable.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_enable.yaml @@ -14,7 +14,8 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_mute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_mute_all.yaml index 6507cf6da6a1..64c28317025a 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_mute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_mute_all.yaml @@ -14,7 +14,8 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_unmute_all.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_unmute_all.yaml index 17c48dae2677..63fa1d2aa50f 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_unmute_all.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@_unmute_all.yaml @@ -14,7 +14,8 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_mute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_mute.yaml index 439445aa29a8..0f2620aff6a1 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_mute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_mute.yaml @@ -14,14 +14,16 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - in: path name: alertInstanceId description: An identifier for the alert instance. required: true schema: type: string - example: dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 + examples: + - dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_unmute.yaml b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_unmute.yaml index 3a7fe8dc1d31..7b1b6abeab39 100644 --- a/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_unmute.yaml +++ b/x-pack/plugins/alerting/docs/openapi/paths/s@{spaceid}@api@alerts@alert@{alertid}@alert_instance@{alertinstanceid}@_unmute.yaml @@ -14,14 +14,16 @@ post: required: true schema: type: string - example: 41893910-6bca-11eb-9e0d-85d233e3ee35 + examples: + - 41893910-6bca-11eb-9e0d-85d233e3ee35 - in: path name: alertInstanceId description: An identifier for the alert instance. required: true schema: type: string - example: dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 + examples: + - dceeb5d0-6b41-11eb-802b-85b0c1bc8ba2 responses: '204': description: Indicates a successful call. diff --git a/x-pack/plugins/alerting/server/application/alerts_filter_query/constants.ts b/x-pack/plugins/alerting/server/application/alerts_filter_query/constants.ts new file mode 100644 index 000000000000..bce6890c22f2 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/alerts_filter_query/constants.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const filterStateStore = { + APP_STATE: 'appState', + GLOBAL_STATE: 'globalState', +} as const; + +export type FilterStateStore = typeof filterStateStore[keyof typeof filterStateStore]; diff --git a/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/alerts_filter_query_schemas.ts b/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/alerts_filter_query_schemas.ts new file mode 100644 index 000000000000..bf5a24b6e439 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/alerts_filter_query_schemas.ts @@ -0,0 +1,28 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { filterStateStore } from '../constants'; + +export const alertsFilterQuerySchema = schema.object({ + kql: schema.string(), + filters: schema.arrayOf( + schema.object({ + query: schema.maybe(schema.recordOf(schema.string(), schema.any())), + meta: schema.recordOf(schema.string(), schema.any()), + $state: schema.maybe( + schema.object({ + store: schema.oneOf([ + schema.literal(filterStateStore.APP_STATE), + schema.literal(filterStateStore.GLOBAL_STATE), + ]), + }) + ), + }) + ), + dsl: schema.maybe(schema.string()), +}); diff --git a/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/index.ts b/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/index.ts new file mode 100644 index 000000000000..5042e3e8265a --- /dev/null +++ b/x-pack/plugins/alerting/server/application/alerts_filter_query/schemas/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { alertsFilterQuerySchema } from './alerts_filter_query_schemas'; diff --git a/x-pack/plugins/alerting/server/application/alerts_filter_query/types/alerts_filter_query.ts b/x-pack/plugins/alerting/server/application/alerts_filter_query/types/alerts_filter_query.ts new file mode 100644 index 000000000000..926d27e89fa9 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/alerts_filter_query/types/alerts_filter_query.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TypeOf } from '@kbn/config-schema'; +import { alertsFilterQuerySchema } from '../schemas/alerts_filter_query_schemas'; + +export type AlertsFilterQuery = TypeOf; diff --git a/x-pack/plugins/alerting/server/application/alerts_filter_query/types/index.ts b/x-pack/plugins/alerting/server/application/alerts_filter_query/types/index.ts new file mode 100644 index 000000000000..2553fd000590 --- /dev/null +++ b/x-pack/plugins/alerting/server/application/alerts_filter_query/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { AlertsFilterQuery } from './alerts_filter_query'; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts b/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts index caa1616d10a7..4b5920d64558 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/constants.ts @@ -13,8 +13,12 @@ export const maintenanceWindowStatus = { } as const; export const maintenanceWindowCategoryIdTypes = { - KIBANA: 'kibana', OBSERVABILITY: 'observability', SECURITY_SOLUTION: 'securitySolution', MANAGEMENT: 'management', } as const; + +export const filterStateStore = { + APP_STATE: 'appState', + GLOBAL_STATE: 'globalState', +} as const; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts b/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts index 99f8e99f3f5e..78227dab5864 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/lib/generate_maintenance_window_events.ts @@ -8,7 +8,8 @@ import _ from 'lodash'; import moment from 'moment-timezone'; import { RRule, Weekday } from '@kbn/rrule'; -import { RRuleParams, MaintenanceWindowSOAttributes, DateRange } from '../../../../common'; +import { RRuleParams, DateRange } from '../../../../common'; +import { MaintenanceWindow } from '../types'; export interface GenerateMaintenanceWindowEventsParams { rRule: RRuleParams; @@ -58,7 +59,7 @@ export const shouldRegenerateEvents = ({ rRule, duration, }: { - maintenanceWindow: MaintenanceWindowSOAttributes; + maintenanceWindow: MaintenanceWindow; rRule?: RRuleParams; duration?: number; }): boolean => { diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts index 1de657bdfd6e..af04b62bfc7d 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.test.ts @@ -133,6 +133,124 @@ describe('MaintenanceWindowClient - create', () => { ); }); + it('should create maintenance window with scoped query', async () => { + jest.useFakeTimers().setSystemTime(new Date('2023-02-26T00:00:00.000Z')); + + const mockMaintenanceWindow = getMockMaintenanceWindow({ + expirationDate: moment(new Date()).tz('UTC').add(1, 'year').toISOString(), + }); + + savedObjectsClient.create.mockResolvedValueOnce({ + attributes: mockMaintenanceWindow, + version: '123', + id: 'test-id', + } as unknown as SavedObject); + + await createMaintenanceWindow(mockContext, { + data: { + title: mockMaintenanceWindow.title, + duration: mockMaintenanceWindow.duration, + rRule: mockMaintenanceWindow.rRule as CreateMaintenanceWindowParams['data']['rRule'], + categoryIds: ['observability', 'securitySolution'], + scopedQuery: { + kql: "_id: '1234'", + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + key: 'kibana.alert.action_group', + field: 'kibana.alert.action_group', + params: { + query: 'test', + }, + type: 'phrase', + }, + $state: { + store: 'appState', + }, + query: { + match_phrase: { + 'kibana.alert.action_group': 'test', + }, + }, + }, + ], + }, + }, + }); + + expect(savedObjectsClient.create).toHaveBeenLastCalledWith( + MAINTENANCE_WINDOW_SAVED_OBJECT_TYPE, + expect.objectContaining({ + title: mockMaintenanceWindow.title, + duration: mockMaintenanceWindow.duration, + rRule: mockMaintenanceWindow.rRule, + enabled: true, + expirationDate: moment(new Date()).tz('UTC').add(1, 'year').toISOString(), + categoryIds: ['observability', 'securitySolution'], + ...updatedMetadata, + }), + { + id: expect.any(String), + } + ); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.kql + ).toEqual(`_id: '1234'`); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.filters[0] + ).toEqual({ + $state: { store: 'appState' }, + meta: { + alias: null, + disabled: false, + field: 'kibana.alert.action_group', + key: 'kibana.alert.action_group', + negate: false, + params: { query: 'test' }, + type: 'phrase', + }, + query: { match_phrase: { 'kibana.alert.action_group': 'test' } }, + }); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.dsl + ).toMatchInlineSnapshot( + `"{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"_id\\":\\"'1234'\\"}}],\\"minimum_should_match\\":1}},{\\"match_phrase\\":{\\"kibana.alert.action_group\\":\\"test\\"}}],\\"should\\":[],\\"must_not\\":[]}}"` + ); + }); + + it('should throw if trying to create a maintenance window with invalid scoped query', async () => { + jest.useFakeTimers().setSystemTime(new Date('2023-02-26T00:00:00.000Z')); + + const mockMaintenanceWindow = getMockMaintenanceWindow({ + expirationDate: moment(new Date()).tz('UTC').add(1, 'year').toISOString(), + }); + + await expect(async () => { + await createMaintenanceWindow(mockContext, { + data: { + title: mockMaintenanceWindow.title, + duration: mockMaintenanceWindow.duration, + rRule: mockMaintenanceWindow.rRule as CreateMaintenanceWindowParams['data']['rRule'], + categoryIds: ['observability', 'securitySolution'], + scopedQuery: { + kql: 'invalid: ', + filters: [], + }, + }, + }); + }).rejects.toThrowErrorMatchingInlineSnapshot(` + "Error validating create maintenance scoped query - Expected \\"(\\", \\"{\\", value, whitespace but end of input found. + invalid: + ---------^" + `); + }); + it('should throw if trying to create a maintenance window with invalid category ids', async () => { jest.useFakeTimers().setSystemTime(new Date('2023-02-26T00:00:00.000Z')); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts index b8fba87b2fc1..78f5e885874b 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/create_maintenance_window.ts @@ -8,6 +8,7 @@ import moment from 'moment'; import Boom from '@hapi/boom'; import { SavedObjectsUtils } from '@kbn/core/server'; +import { buildEsQuery, Filter } from '@kbn/es-query'; import { generateMaintenanceWindowEvents } from '../../lib/generate_maintenance_window_events'; import type { MaintenanceWindowClientContext } from '../../../../../common'; import type { MaintenanceWindow } from '../../types'; @@ -25,7 +26,7 @@ export async function createMaintenanceWindow( ): Promise { const { data } = params; const { savedObjectsClient, getModificationMetadata, logger } = context; - const { title, duration, rRule, categoryIds } = data; + const { title, duration, rRule, categoryIds, scopedQuery } = data; try { createMaintenanceWindowParamsSchema.validate(params); @@ -33,6 +34,25 @@ export async function createMaintenanceWindow( throw Boom.badRequest(`Error validating create maintenance window data - ${error.message}`); } + let scopedQueryWithGeneratedValue = scopedQuery; + try { + if (scopedQuery) { + const dsl = JSON.stringify( + buildEsQuery( + undefined, + [{ query: scopedQuery.kql, language: 'kuery' }], + scopedQuery.filters as Filter[] + ) + ); + scopedQueryWithGeneratedValue = { + ...scopedQuery, + dsl, + }; + } + } catch (error) { + throw Boom.badRequest(`Error validating create maintenance scoped query - ${error.message}`); + } + const id = SavedObjectsUtils.generateId(); const expirationDate = moment().utc().add(1, 'year').toISOString(); const modificationMetadata = await getModificationMetadata(); @@ -43,6 +63,7 @@ export async function createMaintenanceWindow( enabled: true, expirationDate, categoryIds, + scopedQuery: scopedQueryWithGeneratedValue, rRule: rRule as MaintenanceWindow['rRule'], duration, events, diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts index dcb9150f2385..b55a4871d0b6 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/create/schemas/create_maintenance_window_params_schema.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowCategoryIdsSchema } from '../../../schemas'; import { rRuleRequestSchema } from '../../../../r_rule/schemas'; +import { alertsFilterQuerySchema } from '../../../../alerts_filter_query/schemas'; export const createMaintenanceWindowParamsSchema = schema.object({ data: schema.object({ @@ -15,5 +16,6 @@ export const createMaintenanceWindowParamsSchema = schema.object({ duration: schema.number(), rRule: rRuleRequestSchema, categoryIds: maintenanceWindowCategoryIdsSchema, + scopedQuery: schema.maybe(schema.nullable(alertsFilterQuerySchema)), }), }); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts index 84120a5ee8c4..1aca8ab24fcd 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/schemas/update_maintenance_window_params_schema.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowCategoryIdsSchema } from '../../../schemas'; import { rRuleRequestSchema } from '../../../../r_rule/schemas'; +import { alertsFilterQuerySchema } from '../../../../alerts_filter_query/schemas'; export const updateMaintenanceWindowParamsSchema = schema.object({ id: schema.string(), @@ -17,5 +18,6 @@ export const updateMaintenanceWindowParamsSchema = schema.object({ duration: schema.maybe(schema.number()), rRule: schema.maybe(rRuleRequestSchema), categoryIds: maintenanceWindowCategoryIdsSchema, + scopedQuery: schema.maybe(schema.nullable(alertsFilterQuerySchema)), }), }); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts index 966808fed57f..4caef4eca1ba 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.test.ts @@ -207,6 +207,172 @@ describe('MaintenanceWindowClient - update', () => { ); }); + it('should update maintenance window with scoped query', async () => { + jest.useFakeTimers().setSystemTime(new Date(firstTimestamp)); + + const modifiedEvents = [ + { gte: '2023-03-26T00:00:00.000Z', lte: '2023-03-26T00:12:34.000Z' }, + { gte: '2023-04-01T23:00:00.000Z', lte: '2023-04-01T23:43:21.000Z' }, + ]; + const mockMaintenanceWindow = getMockMaintenanceWindow({ + rRule: { + tzid: 'CET', + dtstart: '2023-03-26T00:00:00.000Z', + freq: Frequency.WEEKLY, + count: 5, + } as MaintenanceWindow['rRule'], + events: modifiedEvents, + expirationDate: moment(new Date(firstTimestamp)).tz('UTC').add(2, 'week').toISOString(), + }); + + savedObjectsClient.get.mockResolvedValue({ + attributes: mockMaintenanceWindow, + version: '123', + id: 'test-id', + } as unknown as SavedObject); + + savedObjectsClient.create.mockResolvedValue({ + attributes: { + ...mockMaintenanceWindow, + ...updatedAttributes, + ...updatedMetadata, + }, + id: 'test-id', + } as unknown as SavedObject); + + await updateMaintenanceWindow(mockContext, { + id: 'test-id', + data: { + scopedQuery: { + kql: "_id: '1234'", + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + key: 'kibana.alert.action_group', + field: 'kibana.alert.action_group', + params: { + query: 'test', + }, + type: 'phrase', + }, + $state: { + store: 'appState', + }, + query: { + match_phrase: { + 'kibana.alert.action_group': 'test', + }, + }, + }, + ], + }, + }, + }); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.kql + ).toEqual(`_id: '1234'`); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.filters[0] + ).toEqual({ + $state: { store: 'appState' }, + meta: { + alias: null, + disabled: false, + field: 'kibana.alert.action_group', + key: 'kibana.alert.action_group', + negate: false, + params: { query: 'test' }, + type: 'phrase', + }, + query: { match_phrase: { 'kibana.alert.action_group': 'test' } }, + }); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery!.dsl + ).toMatchInlineSnapshot( + `"{\\"bool\\":{\\"must\\":[],\\"filter\\":[{\\"bool\\":{\\"should\\":[{\\"match\\":{\\"_id\\":\\"'1234'\\"}}],\\"minimum_should_match\\":1}},{\\"match_phrase\\":{\\"kibana.alert.action_group\\":\\"test\\"}}],\\"should\\":[],\\"must_not\\":[]}}"` + ); + }); + + it('should remove maintenance window with scoped query', async () => { + jest.useFakeTimers().setSystemTime(new Date(firstTimestamp)); + + const modifiedEvents = [ + { gte: '2023-03-26T00:00:00.000Z', lte: '2023-03-26T00:12:34.000Z' }, + { gte: '2023-04-01T23:00:00.000Z', lte: '2023-04-01T23:43:21.000Z' }, + ]; + const mockMaintenanceWindow = getMockMaintenanceWindow({ + rRule: { + tzid: 'CET', + dtstart: '2023-03-26T00:00:00.000Z', + freq: Frequency.WEEKLY, + count: 5, + } as MaintenanceWindow['rRule'], + events: modifiedEvents, + expirationDate: moment(new Date(firstTimestamp)).tz('UTC').add(2, 'week').toISOString(), + }); + + savedObjectsClient.get.mockResolvedValue({ + attributes: mockMaintenanceWindow, + version: '123', + id: 'test-id', + } as unknown as SavedObject); + + savedObjectsClient.create.mockResolvedValue({ + attributes: { + ...mockMaintenanceWindow, + ...updatedAttributes, + ...updatedMetadata, + }, + id: 'test-id', + } as unknown as SavedObject); + + await updateMaintenanceWindow(mockContext, { + id: 'test-id', + data: { + scopedQuery: null, + }, + }); + + expect( + (savedObjectsClient.create.mock.calls[0][1] as MaintenanceWindow).scopedQuery + ).toBeNull(); + }); + + it('should throw if updating a maintenance window with invalid scoped query', async () => { + jest.useFakeTimers().setSystemTime(new Date(firstTimestamp)); + const mockMaintenanceWindow = getMockMaintenanceWindow({ + expirationDate: moment(new Date(firstTimestamp)).tz('UTC').subtract(1, 'year').toISOString(), + }); + + savedObjectsClient.get.mockResolvedValueOnce({ + attributes: mockMaintenanceWindow, + version: '123', + id: 'test-id', + } as unknown as SavedObject); + + await expect(async () => { + await updateMaintenanceWindow(mockContext, { + id: 'test-id', + data: { + scopedQuery: { + kql: 'invalid: ', + filters: [], + }, + }, + }); + }).rejects.toThrowErrorMatchingInlineSnapshot(` + "Error validating update maintenance scoped query - Expected \\"(\\", \\"{\\", value, whitespace but end of input found. + invalid: + ---------^" + `); + }); + it('should throw if updating a maintenance window that has expired', async () => { jest.useFakeTimers().setSystemTime(new Date(firstTimestamp)); const mockMaintenanceWindow = getMockMaintenanceWindow({ diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts index f10381defc9b..6b7ab69cc807 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/methods/update/update_maintenance_window.ts @@ -7,6 +7,7 @@ import moment from 'moment'; import Boom from '@hapi/boom'; +import { buildEsQuery, Filter } from '@kbn/es-query'; import type { MaintenanceWindowClientContext } from '../../../../../common'; import type { MaintenanceWindow } from '../../types'; import { @@ -45,7 +46,7 @@ async function updateWithOCC( ): Promise { const { savedObjectsClient, getModificationMetadata, logger } = context; const { id, data } = params; - const { title, enabled, duration, rRule, categoryIds } = data; + const { title, enabled, duration, rRule, categoryIds, scopedQuery } = data; try { updateMaintenanceWindowParamsSchema.validate(params); @@ -53,6 +54,25 @@ async function updateWithOCC( throw Boom.badRequest(`Error validating update maintenance window data - ${error.message}`); } + let scopedQueryWithGeneratedValue = scopedQuery; + try { + if (scopedQuery) { + const dsl = JSON.stringify( + buildEsQuery( + undefined, + [{ query: scopedQuery.kql, language: 'kuery' }], + scopedQuery.filters as Filter[] + ) + ); + scopedQueryWithGeneratedValue = { + ...scopedQuery, + dsl, + }; + } + } catch (error) { + throw Boom.badRequest(`Error validating update maintenance scoped query - ${error.message}`); + } + try { const { attributes, @@ -88,6 +108,9 @@ async function updateWithOCC( ...(title ? { title } : {}), ...(rRule ? { rRule: rRule as MaintenanceWindow['rRule'] } : {}), ...(categoryIds !== undefined ? { categoryIds } : {}), + ...(scopedQueryWithGeneratedValue !== undefined + ? { scopedQuery: scopedQueryWithGeneratedValue } + : {}), ...(typeof duration === 'number' ? { duration } : {}), ...(typeof enabled === 'boolean' ? { enabled } : {}), expirationDate, diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts index 080f5b1bbe67..cf9b69454aa9 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/schemas/maintenance_window_schemas.ts @@ -8,6 +8,7 @@ import { schema } from '@kbn/config-schema'; import { maintenanceWindowStatus, maintenanceWindowCategoryIdTypes } from '../constants'; import { rRuleSchema } from '../../r_rule/schemas'; +import { alertsFilterQuerySchema } from '../../alerts_filter_query/schemas'; export const maintenanceWindowEventSchema = schema.object({ gte: schema.string(), @@ -47,4 +48,5 @@ export const maintenanceWindowSchema = schema.object({ schema.literal(maintenanceWindowStatus.ARCHIVED), ]), categoryIds: maintenanceWindowCategoryIdsSchema, + scopedQuery: schema.maybe(schema.nullable(alertsFilterQuerySchema)), }); diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts index 53996f29694f..6a2f25ce18dd 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_attributes_to_maintenance_window.ts @@ -40,5 +40,6 @@ export const transformMaintenanceWindowAttributesToMaintenanceWindow = ( eventEndTime, status, ...(attributes.categoryIds !== undefined ? { categoryIds: attributes.categoryIds } : {}), + ...(attributes.scopedQuery !== undefined ? { scopedQuery: attributes.scopedQuery } : {}), }; }; diff --git a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts index 35865f38aa9b..9d26443bdc07 100644 --- a/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts +++ b/x-pack/plugins/alerting/server/application/maintenance_window/transforms/transform_maintenance_window_to_maintenance_window_attributes.ts @@ -25,5 +25,8 @@ export const transformMaintenanceWindowToMaintenanceWindowAttributes = ( ...(maintenanceWindow.categoryIds !== undefined ? { categoryIds: maintenanceWindow.categoryIds } : {}), + ...(maintenanceWindow.scopedQuery !== undefined + ? { scopedQuery: maintenanceWindow.scopedQuery } + : {}), }; }; diff --git a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts index 294945ad8203..996f67448c7f 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/bulk_edit/bulk_edit_rules.ts @@ -489,7 +489,7 @@ async function updateRuleAttributesAndParamsInMemory( context, operations, rule: ruleDomain, - ruleActions, + ruleActions: ruleActions as RuleDomain['actions'], // TODO (http-versioning) Remove this cast once we fix injectReferencesIntoActions ruleType, }); diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/action_schemas.ts b/x-pack/plugins/alerting/server/application/rule/schemas/action_schemas.ts index 579f41adb042..7cbadb619908 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/action_schemas.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/action_schemas.ts @@ -7,31 +7,10 @@ import { schema } from '@kbn/config-schema'; import { notifyWhenSchema } from './notify_when_schema'; -import { filterStateStore } from '../constants'; +import { alertsFilterQuerySchema } from '../../alerts_filter_query/schemas'; export const actionParamsSchema = schema.recordOf(schema.string(), schema.maybe(schema.any())); -const actionAlertsFilterQueryFiltersSchema = schema.arrayOf( - schema.object({ - query: schema.maybe(schema.recordOf(schema.string(), schema.any())), - meta: schema.recordOf(schema.string(), schema.any()), - $state: schema.maybe( - schema.object({ - store: schema.oneOf([ - schema.literal(filterStateStore.APP_STATE), - schema.literal(filterStateStore.GLOBAL_STATE), - ]), - }) - ), - }) -); - -const actionDomainAlertsFilterQuerySchema = schema.object({ - kql: schema.string(), - filters: actionAlertsFilterQueryFiltersSchema, - dsl: schema.maybe(schema.string()), -}); - const actionAlertsFilterTimeFrameSchema = schema.object({ days: schema.arrayOf( schema.oneOf([ @@ -52,7 +31,7 @@ const actionAlertsFilterTimeFrameSchema = schema.object({ }); const actionDomainAlertsFilterSchema = schema.object({ - query: schema.maybe(actionDomainAlertsFilterQuerySchema), + query: schema.maybe(alertsFilterQuerySchema), timeframe: schema.maybe(actionAlertsFilterTimeFrameSchema), }); @@ -76,17 +55,8 @@ export const actionDomainSchema = schema.object({ useAlertDataAsTemplate: schema.maybe(schema.boolean()), }); -/** - * Sanitized (non-domain) action schema, returned by rules clients for other solutions - */ -const actionAlertsFilterQuerySchema = schema.object({ - kql: schema.string(), - filters: actionAlertsFilterQueryFiltersSchema, - dsl: schema.maybe(schema.string()), -}); - export const actionAlertsFilterSchema = schema.object({ - query: schema.maybe(actionAlertsFilterQuerySchema), + query: schema.maybe(alertsFilterQuerySchema), timeframe: schema.maybe(actionAlertsFilterTimeFrameSchema), }); diff --git a/x-pack/plugins/alerting/server/data/alerts_filter_query/constants.ts b/x-pack/plugins/alerting/server/data/alerts_filter_query/constants.ts new file mode 100644 index 000000000000..bce6890c22f2 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/alerts_filter_query/constants.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const filterStateStore = { + APP_STATE: 'appState', + GLOBAL_STATE: 'globalState', +} as const; + +export type FilterStateStore = typeof filterStateStore[keyof typeof filterStateStore]; diff --git a/x-pack/plugins/alerting/server/data/alerts_filter_query/types/alerts_filter_query_attributes.ts b/x-pack/plugins/alerting/server/data/alerts_filter_query/types/alerts_filter_query_attributes.ts new file mode 100644 index 000000000000..f740d8070abf --- /dev/null +++ b/x-pack/plugins/alerting/server/data/alerts_filter_query/types/alerts_filter_query_attributes.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 type { FilterStateStore } from '../constants'; + +export interface AlertsFilterAttributes { + query?: Record; + meta: Record; + $state?: { + store: FilterStateStore; + }; +} + +export interface AlertsFilterQueryAttributes { + kql: string; + filters: AlertsFilterAttributes[]; + dsl?: string; +} diff --git a/x-pack/plugins/alerting/server/data/alerts_filter_query/types/index.ts b/x-pack/plugins/alerting/server/data/alerts_filter_query/types/index.ts new file mode 100644 index 000000000000..6258f925b6e7 --- /dev/null +++ b/x-pack/plugins/alerting/server/data/alerts_filter_query/types/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export type { AlertsFilterQueryAttributes } from './alerts_filter_query_attributes'; diff --git a/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts b/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts index 91f4e9517255..afb217abaf13 100644 --- a/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts +++ b/x-pack/plugins/alerting/server/data/maintenance_window/types/maintenance_window_attributes.ts @@ -6,7 +6,8 @@ */ import { RRuleAttributes } from '../../r_rule/types'; -import { MaintenanceWindowCategoryIdTypes } from '../constants'; +import type { MaintenanceWindowCategoryIdTypes } from '../constants'; +import { AlertsFilterQueryAttributes } from '../../alerts_filter_query/types'; export interface MaintenanceWindowEventAttributes { gte: string; @@ -25,4 +26,5 @@ export interface MaintenanceWindowAttributes { createdAt: string; updatedAt: string; categoryIds?: MaintenanceWindowCategoryIdTypes[] | null; + scopedQuery?: AlertsFilterQueryAttributes | null; } diff --git a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts index aa8adda873cd..19a669e6bd33 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts @@ -6,7 +6,6 @@ */ import type { SavedObjectAttributes } from '@kbn/core/server'; -import { Filter } from '@kbn/es-query'; import { IsoWeekday } from '../../../../common'; import { ruleNotifyWhenAttributes, @@ -16,6 +15,7 @@ import { ruleExecutionStatusWarningReasonAttributes, } from '../constants'; import { RRuleAttributes } from '../../r_rule/types'; +import { AlertsFilterQueryAttributes } from '../../alerts_filter_query/types'; export type RuleNotifyWhenAttributes = typeof ruleNotifyWhenAttributes[keyof typeof ruleNotifyWhenAttributes]; @@ -115,11 +115,7 @@ interface AlertsFilterTimeFrameAttributes { } interface AlertsFilterAttributes { - query?: { - kql: string; - filters: Filter[]; - dsl: string; - }; + query?: AlertsFilterQueryAttributes; timeframe?: AlertsFilterTimeFrameAttributes; } diff --git a/x-pack/plugins/alerting/server/lib/license_state.ts b/x-pack/plugins/alerting/server/lib/license_state.ts index c774673934eb..99be775f7c3c 100644 --- a/x-pack/plugins/alerting/server/lib/license_state.ts +++ b/x-pack/plugins/alerting/server/lib/license_state.ts @@ -13,7 +13,7 @@ import { capitalize } from 'lodash'; import { Observable, Subscription } from 'rxjs'; import { LicensingPluginStart } from '@kbn/licensing-plugin/server'; import { ILicense, LicenseType } from '@kbn/licensing-plugin/common/types'; -import { PLUGIN } from '../constants/plugin'; +import { PLUGIN } from '../../common/constants/plugin'; import { getRuleTypeFeatureUsageName } from './get_rule_type_feature_usage_name'; import { RuleType, diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts index 03627c258c5e..6eaa77fc7862 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/create/transforms/transform_create_body/v1.ts @@ -16,5 +16,6 @@ export const transformCreateBody = ( duration: createBody.duration, rRule: createBody.r_rule, categoryIds: createBody.category_ids, + scopedQuery: createBody.scoped_query, }; }; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts index 9da852bd6ebf..96c4e92d4934 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/apis/update/transforms/transform_update_body/v1.ts @@ -11,12 +11,21 @@ import { UpdateMaintenanceWindowParams } from '../../../../../../application/mai export const transformUpdateBody = ( updateBody: UpdateMaintenanceWindowRequestBodyV1 ): UpdateMaintenanceWindowParams['data'] => { - const { title, enabled, duration, r_rule: rRule, category_ids: categoryIds } = updateBody; + const { + title, + enabled, + duration, + r_rule: rRule, + category_ids: categoryIds, + scoped_query: scopedQuery, + } = updateBody; + return { ...(title !== undefined ? { title } : {}), ...(enabled !== undefined ? { enabled } : {}), ...(duration !== undefined ? { duration } : {}), ...(rRule !== undefined ? { rRule } : {}), ...(categoryIds !== undefined ? { categoryIds } : {}), + ...(scopedQuery !== undefined ? { scopedQuery } : {}), }; }; diff --git a/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts index e6e0fb9a6aa4..2d21576773c2 100644 --- a/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/maintenance_window/transforms/transform_maintenance_window_to_response/v1.ts @@ -29,5 +29,8 @@ export const transformMaintenanceWindowToResponse = ( ...(maintenanceWindow.categoryIds !== undefined ? { category_ids: maintenanceWindow.categoryIds } : {}), + ...(maintenanceWindow.scopedQuery !== undefined + ? { scoped_query: maintenanceWindow.scopedQuery } + : {}), }; }; diff --git a/x-pack/plugins/alerting/server/rule_type_registry.test.ts b/x-pack/plugins/alerting/server/rule_type_registry.test.ts index 8e01e7d05cbd..709533bb898f 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.test.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.test.ts @@ -782,6 +782,7 @@ describe('Create Lifecycle', () => { "defaultScheduleInterval": undefined, "doesSetRecoveryContext": false, "enabledInLicense": false, + "fieldsForAAD": undefined, "hasAlertsMappings": true, "hasFieldsForAAD": false, "id": "test", diff --git a/x-pack/plugins/alerting/server/rule_type_registry.ts b/x-pack/plugins/alerting/server/rule_type_registry.ts index d73d28950970..fd32e58335e3 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.ts @@ -419,6 +419,7 @@ export class RuleTypeRegistry { name, minimumLicenseRequired ).isValid, + fieldsForAAD, hasFieldsForAAD: Boolean(fieldsForAAD), hasAlertsMappings: !!alerts, validLegacyConsumers, diff --git a/x-pack/plugins/apm/common/data_source.ts b/x-pack/plugins/apm/common/data_source.ts index f3450fe77542..93d826147369 100644 --- a/x-pack/plugins/apm/common/data_source.ts +++ b/x-pack/plugins/apm/common/data_source.ts @@ -14,7 +14,8 @@ type AnyApmDocumentType = | ApmDocumentType.TransactionEvent | ApmDocumentType.ServiceDestinationMetric | ApmDocumentType.ServiceSummaryMetric - | ApmDocumentType.ErrorEvent; + | ApmDocumentType.ErrorEvent + | ApmDocumentType.SpanEvent; export interface ApmDataSource< TDocumentType extends AnyApmDocumentType = AnyApmDocumentType diff --git a/x-pack/plugins/apm/common/document_type.ts b/x-pack/plugins/apm/common/document_type.ts index 92a17c3125a9..e8a29e8d08c4 100644 --- a/x-pack/plugins/apm/common/document_type.ts +++ b/x-pack/plugins/apm/common/document_type.ts @@ -12,6 +12,7 @@ export enum ApmDocumentType { ServiceDestinationMetric = 'serviceDestinationMetric', ServiceSummaryMetric = 'serviceSummaryMetric', ErrorEvent = 'error', + SpanEvent = 'span', } export type ApmServiceTransactionDocumentType = diff --git a/x-pack/plugins/apm/common/utils/kuery_utils.test.ts b/x-pack/plugins/apm/common/utils/kuery_utils.test.ts new file mode 100644 index 000000000000..556a0f4968fd --- /dev/null +++ b/x-pack/plugins/apm/common/utils/kuery_utils.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { toKueryFilterFormat, mergeKueries } from './kuery_utils'; + +describe('toKueryFilterFormat', () => { + it('returns a single value', () => { + expect(toKueryFilterFormat('key', ['foo'])).toEqual(`key : "foo"`); + }); + + it('returns multiple values default separator', () => { + expect(toKueryFilterFormat('key', ['foo', 'bar', 'baz'])).toEqual( + `key : "foo" OR key : "bar" OR key : "baz"` + ); + }); + + it('returns multiple values custom separator', () => { + expect(toKueryFilterFormat('key', ['foo', 'bar', 'baz'], 'AND')).toEqual( + `key : "foo" AND key : "bar" AND key : "baz"` + ); + }); + + it('return empty string when no hostname', () => { + expect(toKueryFilterFormat('key', [])).toEqual(''); + }); + + describe('mergeKueries', () => { + it('returns empty string when both kueries are empty', () => { + expect(mergeKueries(['', ''])).toEqual(''); + }); + + it('returns only first kuery when second is empty', () => { + expect(mergeKueries(['host.name: "foo"', ''])).toEqual( + 'host.name: "foo"' + ); + }); + + it('returns second kuery when first is empty', () => { + expect(mergeKueries(['', 'host.name: "foo"'])).toEqual( + 'host.name: "foo"' + ); + }); + + it('returns merged kueries with default separator', () => { + expect( + mergeKueries([ + 'host.name: "foo" OR host.name: "bar"', + 'process.id: "1"', + ]) + ).toEqual('host.name: "foo" OR host.name: "bar" AND process.id: "1"'); + }); + + it('uses custom separator', () => { + expect( + mergeKueries(['host.name: "foo"', 'process.id: "1"'], 'OR') + ).toEqual('host.name: "foo" OR process.id: "1"'); + }); + }); +}); diff --git a/x-pack/plugins/apm/common/utils/kuery_utils.ts b/x-pack/plugins/apm/common/utils/kuery_utils.ts new file mode 100644 index 000000000000..1caf154a0d5f --- /dev/null +++ b/x-pack/plugins/apm/common/utils/kuery_utils.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { isEmpty } from 'lodash'; + +type Separator = 'OR' | 'AND'; + +export const toKueryFilterFormat = ( + key: string, + values: string[], + separator: Separator = 'OR' +) => values.map((value) => `${key} : "${value}"`).join(` ${separator} `); + +export const mergeKueries = (filters: string[], separator: Separator = 'AND') => + filters.filter((filter) => !isEmpty(filter)).join(` ${separator} `); diff --git a/x-pack/plugins/apm/common/utils/to_kuery_filter_format.test.ts b/x-pack/plugins/apm/common/utils/to_kuery_filter_format.test.ts deleted file mode 100644 index 0a1e01d8404f..000000000000 --- a/x-pack/plugins/apm/common/utils/to_kuery_filter_format.test.ts +++ /dev/null @@ -1,29 +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 { toKueryFilterFormat } from './to_kuery_filter_format'; - -describe('toKueryFilterFormat', () => { - it('returns a single value', () => { - expect(toKueryFilterFormat('key', ['foo'])).toEqual(`key : "foo"`); - }); - - it('returns multiple values default separator', () => { - expect(toKueryFilterFormat('key', ['foo', 'bar', 'baz'])).toEqual( - `key : "foo" OR key : "bar" OR key : "baz"` - ); - }); - - it('returns multiple values custom separator', () => { - expect(toKueryFilterFormat('key', ['foo', 'bar', 'baz'], 'AND')).toEqual( - `key : "foo" AND key : "bar" AND key : "baz"` - ); - }); - - it('return empty string when no hostname', () => { - expect(toKueryFilterFormat('key', [])).toEqual(''); - }); -}); diff --git a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx index 28865a8ad5f1..46f5045dc43e 100644 --- a/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx +++ b/x-pack/plugins/apm/public/components/app/metrics_details/service_node_metrics/index.tsx @@ -22,6 +22,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import React from 'react'; +import { ApmDocumentType } from '../../../../../common/document_type'; import { getServiceNodeName, SERVICE_NODE_NAME_MISSING, @@ -33,6 +34,7 @@ import { ChartPointerEventContextProvider } from '../../../../context/chart_poin import { useApmParams } from '../../../../hooks/use_apm_params'; import { useApmRouter } from '../../../../hooks/use_apm_router'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; +import { usePreferredDataSourceAndBucketSize } from '../../../../hooks/use_preferred_data_source_and_bucket_size'; import { useServiceMetricChartsFetcher } from '../../../../hooks/use_service_metric_charts_fetcher'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { truncate, unit } from '../../../../utils/style'; @@ -83,9 +85,17 @@ export function ServiceNodeMetrics({ serviceNodeName }: Props) { environment, }); + const preferred = usePreferredDataSourceAndBucketSize({ + start, + end, + kuery, + type: ApmDocumentType.ServiceTransactionMetric, + numBuckets: 100, + }); + const { data: { host, containerId } = INITIAL_DATA, status } = useFetcher( (callApmApi) => { - if (start && end) { + if (start && end && preferred) { return callApmApi( 'GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata', { @@ -96,13 +106,15 @@ export function ServiceNodeMetrics({ serviceNodeName }: Props) { start, end, environment, + documentType: preferred.source.documentType, + rollupInterval: preferred.source.rollupInterval, }, }, } ); } }, - [kuery, serviceName, serviceNodeName, start, end, environment] + [kuery, serviceName, serviceNodeName, start, end, environment, preferred] ); const { docLinks } = useApmPluginContext().core; diff --git a/x-pack/plugins/apm/public/components/app/profiling_overview/index.tsx b/x-pack/plugins/apm/public/components/app/profiling_overview/index.tsx index 6c6bd7a356d7..cdd9699ebadc 100644 --- a/x-pack/plugins/apm/public/components/app/profiling_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/profiling_overview/index.tsx @@ -17,7 +17,9 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { EmbeddableProfilingSearchBar } from '@kbn/observability-shared-plugin/public'; import React, { useMemo } from 'react'; +import { useHistory } from 'react-router-dom'; import { ApmDocumentType } from '../../../../common/document_type'; import { useApmParams } from '../../../hooks/use_apm_params'; import { useLocalStorage } from '../../../hooks/use_local_storage'; @@ -25,17 +27,19 @@ import { usePreferredDataSourceAndBucketSize } from '../../../hooks/use_preferre import { useProfilingPlugin } from '../../../hooks/use_profiling_plugin'; import { useTimeRange } from '../../../hooks/use_time_range'; import { ApmPluginStartDeps } from '../../../plugin'; +import { push } from '../../shared/links/url_helpers'; import { ProfilingFlamegraph } from './profiling_flamegraph'; import { ProfilingTopNFunctions } from './profiling_top_functions'; export function ProfilingOverview() { + const history = useHistory(); const { services } = useKibana(); const { path: { serviceName }, query: { rangeFrom, rangeTo, environment, kuery }, } = useApmParams('/services/{serviceName}/profiling'); const { isProfilingAvailable } = useProfilingPlugin(); - const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { start, end, refreshTimeRange } = useTimeRange({ rangeFrom, rangeTo }); const preferred = usePreferredDataSourceAndBucketSize({ start, end, @@ -43,6 +47,7 @@ export function ProfilingOverview() { type: ApmDocumentType.TransactionMetric, numBuckets: 20, }); + const [ apmUniversalProfilingShowCallout, setAPMUniversalProfilingShowCallout, @@ -67,6 +72,7 @@ export function ProfilingOverview() { end={end} environment={environment} dataSource={preferred?.source} + kuery={kuery} /> ), @@ -87,12 +93,13 @@ export function ProfilingOverview() { startIndex={0} endIndex={10} dataSource={preferred?.source} + kuery={kuery} /> ), }, ]; - }, [end, environment, preferred?.source, serviceName, start]); + }, [end, environment, kuery, preferred?.source, serviceName, start]); if (!isProfilingAvailable) { return null; @@ -147,6 +154,22 @@ export function ProfilingOverview() { )} + { + push(history, { + query: { + kuery: next.query, + rangeFrom: next.dateRange.from, + rangeTo: next.dateRange.to, + }, + }); + }} + onRefresh={refreshTimeRange} + /> + ; + kuery: string; } export function ProfilingFlamegraph({ @@ -44,6 +48,7 @@ export function ProfilingFlamegraph({ serviceName, environment, dataSource, + kuery, }: Props) { const { profilingLocators } = useProfilingPlugin(); @@ -61,13 +66,14 @@ export function ProfilingFlamegraph({ environment, documentType: dataSource.documentType, rollupInterval: dataSource.rollupInterval, + kuery, }, }, } ); } }, - [dataSource, serviceName, start, end, environment] + [dataSource, serviceName, start, end, environment, kuery] ); const hostNamesKueryFormat = toKueryFilterFormat( @@ -86,7 +92,7 @@ export function ProfilingFlamegraph({ {i18n.translate('xpack.apm.profiling.flamegraph.link', { diff --git a/x-pack/plugins/apm/public/components/app/profiling_overview/profiling_top_functions.tsx b/x-pack/plugins/apm/public/components/app/profiling_overview/profiling_top_functions.tsx index 0c2a22504072..7b428802fbfc 100644 --- a/x-pack/plugins/apm/public/components/app/profiling_overview/profiling_top_functions.tsx +++ b/x-pack/plugins/apm/public/components/app/profiling_overview/profiling_top_functions.tsx @@ -9,13 +9,16 @@ import { EuiFlexGroup, EuiFlexItem, EuiLink, EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { EmbeddableFunctions } from '@kbn/observability-shared-plugin/public'; import React from 'react'; +import { ApmDataSourceWithSummary } from '../../../../common/data_source'; +import { ApmDocumentType } from '../../../../common/document_type'; import { HOST_NAME } from '../../../../common/es_fields/apm'; -import { toKueryFilterFormat } from '../../../../common/utils/to_kuery_filter_format'; +import { + mergeKueries, + toKueryFilterFormat, +} from '../../../../common/utils/kuery_utils'; import { isPending, useFetcher } from '../../../hooks/use_fetcher'; import { useProfilingPlugin } from '../../../hooks/use_profiling_plugin'; import { HostnamesFilterWarning } from './host_names_filter_warning'; -import { ApmDataSourceWithSummary } from '../../../../common/data_source'; -import { ApmDocumentType } from '../../../../common/document_type'; interface Props { serviceName: string; @@ -27,6 +30,7 @@ interface Props { dataSource?: ApmDataSourceWithSummary< ApmDocumentType.TransactionMetric | ApmDocumentType.TransactionEvent >; + kuery: string; } export function ProfilingTopNFunctions({ @@ -37,6 +41,7 @@ export function ProfilingTopNFunctions({ startIndex, endIndex, dataSource, + kuery, }: Props) { const { profilingLocators } = useProfilingPlugin(); @@ -56,13 +61,23 @@ export function ProfilingTopNFunctions({ endIndex, documentType: dataSource.documentType, rollupInterval: dataSource.rollupInterval, + kuery, }, }, } ); } }, - [dataSource, serviceName, start, end, environment, startIndex, endIndex] + [ + dataSource, + serviceName, + start, + end, + environment, + startIndex, + endIndex, + kuery, + ] ); const hostNamesKueryFormat = toKueryFilterFormat( @@ -81,7 +96,7 @@ export function ProfilingTopNFunctions({ {i18n.translate('xpack.apm.profiling.topnFunctions.link', { diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx index 081a24ceb442..b3e36fc8bebb 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx @@ -327,6 +327,7 @@ export function ServiceList({ } = useApmParams('/services'); const { kuery } = query; + const { fallbackToTransactions } = useFallbackToTransactionsFetcher({ kuery, }); diff --git a/x-pack/plugins/apm/public/components/app/top_traces_overview/index.tsx b/x-pack/plugins/apm/public/components/app/top_traces_overview/index.tsx index 486a54b40009..3c314f638977 100644 --- a/x-pack/plugins/apm/public/components/app/top_traces_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/top_traces_overview/index.tsx @@ -19,12 +19,12 @@ export function TopTracesOverview() { const { query: { environment, kuery, rangeFrom, rangeTo }, } = useApmParams('/traces'); + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { fallbackToTransactions } = useFallbackToTransactionsFetcher({ kuery, }); - const { start, end } = useTimeRange({ rangeFrom, rangeTo }); - const response = useProgressiveFetcher( (callApmApi) => { if (start && end) { diff --git a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx index 56deaaa2e6d6..f2601e392b27 100644 --- a/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/service_detail/index.tsx @@ -371,9 +371,7 @@ export const serviceDetailRoute = { }), element: , searchBarOptions: { - showTimeComparison: false, - showTransactionTypeSelector: false, - showQueryInput: false, + hidden: true, }, }), }, diff --git a/x-pack/plugins/apm/public/hooks/use_fallback_to_transactions_fetcher.tsx b/x-pack/plugins/apm/public/hooks/use_fallback_to_transactions_fetcher.tsx index f1d30f423707..6ffebcb95f2a 100644 --- a/x-pack/plugins/apm/public/hooks/use_fallback_to_transactions_fetcher.tsx +++ b/x-pack/plugins/apm/public/hooks/use_fallback_to_transactions_fetcher.tsx @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ + import { getKueryWithMobileFilters } from '../../common/utils/get_kuery_with_mobile_filters'; import { useApmParams } from './use_apm_params'; import { useFetcher } from './use_fetcher'; @@ -33,11 +34,17 @@ export function useFallbackToTransactionsFetcher({ kuery }: { kuery: string }) { const { data = { fallbackToTransactions: false } } = useFetcher( (callApmApi) => { - return callApmApi('GET /internal/apm/fallback_to_transactions', { - params: { - query: { kuery: kueryWithFilters, start, end }, - }, - }); + if (start && end) { + return callApmApi('GET /internal/apm/fallback_to_transactions', { + params: { + query: { + kuery: kueryWithFilters, + start, + end, + }, + }, + }); + } }, [kueryWithFilters, start, end] ); diff --git a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts index 346921960f92..4524d5121b78 100644 --- a/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts +++ b/x-pack/plugins/apm/server/lib/connections/get_connection_stats/get_stats.ts @@ -9,7 +9,6 @@ import { sum } from 'lodash'; import objectHash from 'object-hash'; import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { rangeQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; import { ENVIRONMENT_NOT_DEFINED } from '../../../../common/environment_filter_values'; @@ -28,6 +27,8 @@ import { import { getBucketSize } from '../../../../common/utils/get_bucket_size'; import { EventOutcome } from '../../../../common/event_outcome'; import { NodeType } from '../../../../common/connections'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; import { excludeRumExitSpansQuery } from '../exclude_rum_exit_spans_query'; import { APMEventClient } from '../../helpers/create_es_client/create_apm_event_client'; import { getDocumentTypeFilterForServiceDestinationStatistics } from '../../helpers/spans/get_is_using_service_destination_metrics'; @@ -55,7 +56,12 @@ export const getStats = async ({ const response = await apmEventClient.search('get_connection_stats', { apm: { - events: [ProcessorEvent.metric], + sources: [ + { + documentType: ApmDocumentType.ServiceDestinationMetric, + rollupInterval: RollupInterval.OneMinute, + }, + ], }, body: { track_total_hits: true, diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts index 1046a2ad47cf..85ac6689f5df 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts @@ -57,9 +57,9 @@ export function getRequestBase(options: { if ('sources' in options.apm) { options.apm.sources.forEach((source) => { - const { getQuery } = getConfigForDocumentType(source.documentType); - if (getQuery) { - filters.push(getQuery(source.rollupInterval)); + const documentTypeConfig = getConfigForDocumentType(source.documentType); + if ('getQuery' in documentTypeConfig) { + filters.push(documentTypeConfig.getQuery(source.rollupInterval)); } }); } diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts index fcac29b1d57d..53e4c91f384f 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts @@ -62,13 +62,11 @@ type APMEventTermsEnumRequest = APMEventWrapper; type APMEventEqlSearchRequest = APMEventWrapper; type APMEventFieldCapsRequest = APMEventWrapper; -// These keys shoul all be `ProcessorEvent.x`, but until TypeScript 4.2 we're inlining them here. -// See https://github.com/microsoft/TypeScript/issues/37888 type TypeOfProcessorEvent = { - error: APMError; - transaction: Transaction; - span: Span; - metric: Metric; + [ProcessorEvent.error]: APMError; + [ProcessorEvent.transaction]: Transaction; + [ProcessorEvent.span]: Span; + [ProcessorEvent.metric]: Metric; }[T]; type TypedLogEventSearchResponse = @@ -77,15 +75,13 @@ type TypedLogEventSearchResponse = type TypedSearchResponse = InferSearchResponseOf< TypeOfProcessorEvent< - ValuesType< - TParams['apm'] extends { events: ProcessorEvent[] } - ? TParams['apm']['events'] - : TParams['apm'] extends { sources: ApmDataSource[] } - ? ProcessorEventOfDocumentType< - ValuesType['documentType'] - > - : never - > + TParams['apm'] extends { events: ProcessorEvent[] } + ? ValuesType + : TParams['apm'] extends { sources: ApmDataSource[] } + ? ProcessorEventOfDocumentType< + ValuesType['documentType'] + > + : never >, TParams >; diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/document_type.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/document_type.ts index a3f5ff8d5683..bcafd76b8e22 100644 --- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/document_type.ts +++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/document_type.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { ApmDocumentType } from '../../../../common/document_type'; import { @@ -33,18 +32,11 @@ function getDefaultFilter( ]; } -const documentTypeConfigMap: Record< - ApmDocumentType, - { - processorEvent: ProcessorEvent; - getQuery?: (rollupInterval: RollupInterval) => QueryDslQueryContainer; - rollupIntervals: RollupInterval[]; - } -> = { +const documentTypeConfigMap = { [ApmDocumentType.ServiceTransactionMetric]: { processorEvent: ProcessorEvent.metric, - getQuery: (rollupInterval) => ({ + getQuery: (rollupInterval: RollupInterval) => ({ bool: { filter: getDefaultFilter('service_transaction', rollupInterval), }, @@ -53,7 +45,7 @@ const documentTypeConfigMap: Record< }, [ApmDocumentType.ServiceSummaryMetric]: { processorEvent: ProcessorEvent.metric, - getQuery: (rollupInterval) => ({ + getQuery: (rollupInterval: RollupInterval) => ({ bool: { filter: getDefaultFilter('service_summary', rollupInterval), }, @@ -62,7 +54,7 @@ const documentTypeConfigMap: Record< }, [ApmDocumentType.TransactionMetric]: { processorEvent: ProcessorEvent.metric, - getQuery: (rollupInterval) => ({ + getQuery: (rollupInterval: RollupInterval) => ({ bool: { filter: rollupInterval === RollupInterval.OneMinute @@ -79,7 +71,7 @@ const documentTypeConfigMap: Record< [ApmDocumentType.ServiceDestinationMetric]: { processorEvent: ProcessorEvent.metric, rollupIntervals: defaultRollupIntervals, - getQuery: (rollupInterval) => ({ + getQuery: (rollupInterval: RollupInterval) => ({ bool: { filter: rollupInterval === RollupInterval.OneMinute @@ -92,7 +84,11 @@ const documentTypeConfigMap: Record< processorEvent: ProcessorEvent.error, rollupIntervals: [RollupInterval.None], }, -}; + [ApmDocumentType.SpanEvent]: { + processorEvent: ProcessorEvent.span, + rollupIntervals: [RollupInterval.None], + }, +} as const; type DocumentTypeConfigOf = typeof documentTypeConfigMap[TApmDocumentType]; diff --git a/x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap b/x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap index 325ce29af118..192df5cc8eb3 100644 --- a/x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap +++ b/x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap @@ -96,8 +96,11 @@ Array [ "get_has_transactions", Object { "apm": Object { - "events": Array [ - "transaction", + "sources": Array [ + Object { + "documentType": "transactionEvent", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts index 20832c70d007..0ba5fb5f92af 100644 --- a/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts +++ b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts @@ -6,10 +6,11 @@ */ import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { getSearchTransactionsEvents } from '.'; import { APMEventClient } from '../create_es_client/create_apm_event_client'; import { SearchAggregatedTransactionSetting } from '../../../../common/aggregated_transactions'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; import { APMConfig } from '../../..'; export async function getIsUsingTransactionEvents({ @@ -63,7 +64,12 @@ async function getHasTransactions({ }) { const response = await apmEventClient.search('get_has_transactions', { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: 1, diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/get_buckets.test.ts.snap b/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/get_buckets.test.ts.snap index 54705647dc6a..4145b9ae31da 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/get_buckets.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/get_buckets.test.ts.snap @@ -6,8 +6,11 @@ Array [ "get_error_distribution_buckets", Object { "apm": Object { - "events": Array [ - "error", + "sources": Array [ + Object { + "documentType": "error", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/queries.test.ts.snap index a3127ee28c0b..480283b7a690 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/errors/distribution/__snapshots__/queries.test.ts.snap @@ -3,8 +3,11 @@ exports[`error distribution queries fetches an error distribution 1`] = ` Object { "apm": Object { - "events": Array [ - "error", + "sources": Array [ + Object { + "documentType": "error", + "rollupInterval": "none", + }, ], }, "body": Object { @@ -50,8 +53,11 @@ Object { exports[`error distribution queries fetches an error distribution with a group id 1`] = ` Object { "apm": Object { - "events": Array [ - "error", + "sources": Array [ + Object { + "documentType": "error", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts index 4a3fc6d969cd..a8994fd4ec2c 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.test.ts @@ -6,7 +6,8 @@ */ import { getBuckets } from './get_buckets'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; describe('get buckets', () => { let clientSpy: jest.Mock; @@ -42,6 +43,11 @@ describe('get buckets', () => { it('should limit query results to error documents', () => { const query = clientSpy.mock.calls[0][1]; - expect(query.apm.events).toEqual([ProcessorEvent.error]); + expect(query.apm.sources).toEqual([ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ]); }); }); diff --git a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts index 72e9b1c1b2d5..83e9d4475bfb 100644 --- a/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts +++ b/x-pack/plugins/apm/server/routes/errors/distribution/get_buckets.ts @@ -10,8 +10,9 @@ import { kqlQuery, termQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { ApmDocumentType } from '../../../../common/document_type'; import { ERROR_GROUP_ID, SERVICE_NAME } from '../../../../common/es_fields/apm'; +import { RollupInterval } from '../../../../common/rollup'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; @@ -36,7 +37,12 @@ export async function getBuckets({ }) { const params = { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts b/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts index 31695c0a127d..41f49959aa70 100644 --- a/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts +++ b/x-pack/plugins/apm/server/routes/errors/erroneous_transactions/get_top_erroneous_transactions.ts @@ -17,7 +17,6 @@ import { kqlQuery, termQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { keyBy } from 'lodash'; import { ERROR_GROUP_ID, @@ -28,6 +27,8 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { getBucketSize } from '../../../../common/utils/get_bucket_size'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; async function getTopErroneousTransactions({ @@ -65,7 +66,12 @@ async function getTopErroneousTransactions({ const res = await apmEventClient.search('get_top_erroneous_transactions', { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, @@ -112,17 +118,19 @@ async function getTopErroneousTransactions({ return ( res.aggregations?.top_five_transactions.buckets.map( - ({ key, doc_count: docCount, sample, timeseries }) => ({ - transactionName: key as string, - transactionType: sample.hits.hits[0]._source.transaction?.type, - occurrences: docCount, - timeseries: timeseries.buckets.map((timeseriesBucket) => { - return { - x: timeseriesBucket.key + offsetInMs, - y: timeseriesBucket.doc_count, - }; - }), - }) + ({ key, doc_count: docCount, sample, timeseries }) => { + return { + transactionName: key as string, + transactionType: sample.hits.hits[0]._source.transaction?.type, + occurrences: docCount, + timeseries: timeseries.buckets.map((timeseriesBucket) => { + return { + x: timeseriesBucket.key + offsetInMs, + y: timeseriesBucket.doc_count, + }; + }), + }; + } ) ?? [] ); } diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts index cf799a47f7dc..182fe0a1cdd8 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts @@ -11,7 +11,6 @@ import { rangeQuery, termQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { ERROR_CULPRIT, ERROR_EXC_HANDLED, @@ -26,6 +25,8 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { getErrorName } from '../../../lib/helpers/get_error_name'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; export type ErrorGroupMainStatisticsResponse = Array<{ groupId: string; @@ -75,7 +76,12 @@ export async function getErrorGroupMainStatistics({ 'get_error_group_main_statistics', { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, @@ -128,16 +134,19 @@ export async function getErrorGroupMainStatistics({ ); return ( - response.aggregations?.error_groups.buckets.map((bucket) => ({ - groupId: bucket.key as string, - name: getErrorName(bucket.sample.hits.hits[0]._source), - lastSeen: new Date( - bucket.sample.hits.hits[0]?._source['@timestamp'] - ).getTime(), - occurrences: bucket.doc_count, - culprit: bucket.sample.hits.hits[0]?._source.error.culprit, - handled: bucket.sample.hits.hits[0]?._source.error.exception?.[0].handled, - type: bucket.sample.hits.hits[0]?._source.error.exception?.[0].type, - })) ?? [] + response.aggregations?.error_groups.buckets.map((bucket) => { + return { + groupId: bucket.key as string, + name: getErrorName(bucket.sample.hits.hits[0]._source), + lastSeen: new Date( + bucket.sample.hits.hits[0]._source['@timestamp'] + ).getTime(), + occurrences: bucket.doc_count, + culprit: bucket.sample.hits.hits[0]._source.error.culprit, + handled: + bucket.sample.hits.hits[0]._source.error.exception?.[0].handled, + type: bucket.sample.hits.hits[0]._source.error.exception?.[0].type, + }; + }) ?? [] ); } diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts index 2796ec590ad4..0a154d3ad13f 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample_ids.ts @@ -6,7 +6,6 @@ */ import { rangeQuery, kqlQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; import { ERROR_GROUP_ID, @@ -16,6 +15,8 @@ import { } from '../../../../common/es_fields/apm'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; const ERROR_SAMPLES_SIZE = 10000; @@ -41,9 +42,14 @@ export async function getErrorGroupSampleIds({ start: number; end: number; }): Promise { - const params = { + const resp = await apmEventClient.search('get_error_group_sample_ids', { apm: { - events: [ProcessorEvent.error as const], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: ERROR_SAMPLES_SIZE, @@ -66,13 +72,11 @@ export async function getErrorGroupSampleIds({ { '@timestamp': { order: 'desc' } }, // sort by timestamp to get the most recent error ] as const), }, - }; - - const resp = await apmEventClient.search( - 'get_error_group_sample_ids', - params - ); - const errorSampleIds = resp.hits.hits.map((item) => item._source.error.id); + }); + const errorSampleIds = resp.hits.hits.map((item) => { + const source = item._source; + return source.error.id; + }); return { errorSampleIds, diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts index cb11c0154be6..348949d3ecca 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_sample_details.ts @@ -6,9 +6,10 @@ */ import { rangeQuery, kqlQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { ERROR_ID, SERVICE_NAME } from '../../../../common/es_fields/apm'; import { environmentQuery } from '../../../../common/utils/environment_query'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { getTransaction } from '../../transactions/get_transaction'; import { Transaction } from '../../../../typings/es_schemas/ui/transaction'; @@ -38,7 +39,12 @@ export async function getErrorSampleDetails({ }): Promise { const params = { apm: { - events: [ProcessorEvent.error as const], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent as const, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts index 8deb85264e01..b6ea22e03d50 100644 --- a/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts +++ b/x-pack/plugins/apm/server/routes/metrics/serverless/get_serverless_summary.ts @@ -10,6 +10,7 @@ import { kqlQuery, rangeQuery, } from '@kbn/observability-plugin/server'; +import { ApmDocumentType } from '../../../../common/document_type'; import { FAAS_BILLED_DURATION, FAAS_DURATION, @@ -20,6 +21,7 @@ import { METRIC_SYSTEM_TOTAL_MEMORY, SERVICE_NAME, } from '../../../../common/es_fields/apm'; +import { RollupInterval } from '../../../../common/rollup'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; import { computeUsageAvgScript } from './get_compute_usage_chart'; @@ -52,7 +54,12 @@ async function getServerlessTransactionThroughput({ }) { const params = { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: true, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_device_os_app.ts b/x-pack/plugins/apm/server/routes/mobile/get_device_os_app.ts index e2194b994b02..80fae958b6c5 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_device_os_app.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_device_os_app.ts @@ -10,7 +10,6 @@ import { kqlQuery, rangeQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { DEVICE_MODEL_IDENTIFIER, HOST_OS_VERSION, @@ -19,6 +18,8 @@ import { TRANSACTION_TYPE, } from '../../../common/es_fields/apm'; import { environmentQuery } from '../../../common/utils/environment_query'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getDeviceOSApp({ @@ -42,7 +43,12 @@ export async function getDeviceOSApp({ }) { return await apmEventClient.search('get_mobile_device_os_app', { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_crash_rate.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_crash_rate.ts index bf498bf70460..e60d0ff15c62 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_crash_rate.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_crash_rate.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { kqlQuery, rangeQuery, @@ -23,6 +22,8 @@ import { import { environmentQuery } from '../../../common/utils/environment_query'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_previous_period_coordinate'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; export interface CrashRateTimeseries { currentPeriod: { timeseries: Coordinate[]; value: Maybe }; @@ -70,7 +71,12 @@ async function getMobileCrashTimeseries({ const response = await apmEventClient.search('get_mobile_crash_rate', { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_crashes_by_location.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_crashes_by_location.ts index 855ae8fb35d0..e91214af444b 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_crashes_by_location.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_crashes_by_location.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { kqlQuery, rangeQuery, @@ -16,6 +15,8 @@ import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_ev import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSize } from '../../../common/utils/get_bucket_size'; import { environmentQuery } from '../../../common/utils/environment_query'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; interface Props { kuery: string; @@ -64,7 +65,12 @@ export async function getCrashesByLocation({ }; const response = await apmEventClient.search('get_mobile_location_crashes', { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions.ts index e3ccd83c20bf..9168101ebc40 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { kqlQuery, rangeQuery, @@ -23,6 +22,8 @@ import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_ev import { getBucketSize } from '../../../common/utils/get_bucket_size'; import { Coordinate } from '../../../typings/timeseries'; import { Maybe } from '../../../typings/common'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; export interface SessionsTimeseries { currentPeriod: { timeseries: Coordinate[]; value: Maybe }; @@ -70,7 +71,12 @@ async function getSessionTimeseries({ const response = await apmEventClient.search('get_mobile_sessions', { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions_by_location.ts b/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions_by_location.ts index 95ad146f585f..7543d097d888 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions_by_location.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_mobile_sessions_by_location.ts @@ -10,12 +10,13 @@ import { kqlQuery, rangeQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { SERVICE_NAME, SESSION_ID } from '../../../common/es_fields/apm'; import { environmentQuery } from '../../../common/utils/environment_query'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { getOffsetInMs } from '../../../common/utils/get_offset_in_ms'; import { getBucketSize } from '../../../common/utils/get_bucket_size'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; interface Props { kuery: string; @@ -65,7 +66,12 @@ export async function getSessionsByLocation({ const response = await apmEventClient.search('get_mobile_location_sessions', { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/mobile/get_nct.ts b/x-pack/plugins/apm/server/routes/mobile/get_nct.ts index 829f40962f84..f84701ecfb29 100644 --- a/x-pack/plugins/apm/server/routes/mobile/get_nct.ts +++ b/x-pack/plugins/apm/server/routes/mobile/get_nct.ts @@ -10,12 +10,13 @@ import { kqlQuery, rangeQuery, } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { NETWORK_CONNECTION_TYPE, SERVICE_NAME, } from '../../../common/es_fields/apm'; import { environmentQuery } from '../../../common/utils/environment_query'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; export async function getNCT({ @@ -38,7 +39,12 @@ export async function getNCT({ }) { return await apmEventClient.search('get_mobile_nct', { apm: { - events: [ProcessorEvent.span], + sources: [ + { + documentType: ApmDocumentType.SpanEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/profiling/route.ts b/x-pack/plugins/apm/server/routes/profiling/route.ts index 9d5853c28833..16b1b5fd5661 100644 --- a/x-pack/plugins/apm/server/routes/profiling/route.ts +++ b/x-pack/plugins/apm/server/routes/profiling/route.ts @@ -10,11 +10,15 @@ import type { BaseFlameGraph, TopNFunctions } from '@kbn/profiling-utils'; import * as t from 'io-ts'; import { profilingUseLegacyFlamegraphAPI } from '@kbn/observability-plugin/common'; import { HOST_NAME } from '../../../common/es_fields/apm'; -import { toKueryFilterFormat } from '../../../common/utils/to_kuery_filter_format'; +import { + mergeKueries, + toKueryFilterFormat, +} from '../../../common/utils/kuery_utils'; import { getApmEventClient } from '../../lib/helpers/get_apm_event_client'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { environmentRt, + kueryRt, rangeRt, serviceTransactionDataSourceRt, } from '../default_api_types'; @@ -28,6 +32,7 @@ const profilingFlamegraphRoute = createApmServerRoute({ rangeRt, environmentRt, serviceTransactionDataSourceRt, + kueryRt, ]), }), options: { tags: ['access:apm'] }, @@ -48,7 +53,7 @@ const profilingFlamegraphRoute = createApmServerRoute({ await plugins.profilingDataAccess?.start(), ]); if (profilingDataAccessStart) { - const { start, end, environment, documentType, rollupInterval } = + const { start, end, environment, documentType, rollupInterval, kuery } = params.query; const { serviceName } = params.path; @@ -71,7 +76,10 @@ const profilingFlamegraphRoute = createApmServerRoute({ esClient: esClient.asCurrentUser, rangeFromMs: start, rangeToMs: end, - kuery: toKueryFilterFormat(HOST_NAME, serviceHostNames), + kuery: mergeKueries([ + `(${toKueryFilterFormat(HOST_NAME, serviceHostNames)})`, + kuery, + ]), useLegacyFlamegraphAPI, }); @@ -91,6 +99,7 @@ const profilingFunctionsRoute = createApmServerRoute({ environmentRt, serviceTransactionDataSourceRt, t.type({ startIndex: toNumberRt, endIndex: toNumberRt }), + kueryRt, ]), }), options: { tags: ['access:apm'] }, @@ -113,6 +122,7 @@ const profilingFunctionsRoute = createApmServerRoute({ endIndex, documentType, rollupInterval, + kuery, } = params.query; const { serviceName } = params.path; @@ -134,7 +144,10 @@ const profilingFunctionsRoute = createApmServerRoute({ esClient: esClient.asCurrentUser, rangeFromMs: start, rangeToMs: end, - kuery: toKueryFilterFormat(HOST_NAME, serviceHostNames), + kuery: mergeKueries([ + `(${toKueryFilterFormat(HOST_NAME, serviceHostNames)})`, + kuery, + ]), startIndex, endIndex, }); diff --git a/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts b/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts index e327bf1e7cdb..033e34308478 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts +++ b/x-pack/plugins/apm/server/routes/services/get_service_node_metadata.ts @@ -6,7 +6,6 @@ */ import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { HOST_NAME, CONTAINER_ID } from '../../../common/es_fields/apm'; import { NOT_AVAILABLE_LABEL } from '../../../common/i18n'; import { SERVICE_NAME, SERVICE_NODE_NAME } from '../../../common/es_fields/apm'; @@ -15,6 +14,8 @@ import { serviceNodeNameQuery, } from '../../../common/utils/environment_query'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmServiceTransactionDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; export interface ServiceNodeMetadataResponse { host: string | number; @@ -29,6 +30,8 @@ export async function getServiceNodeMetadata({ start, end, environment, + documentType, + rollupInterval, }: { kuery: string; serviceName: string; @@ -37,10 +40,17 @@ export async function getServiceNodeMetadata({ start: number; end: number; environment: string; + documentType: ApmServiceTransactionDocumentType; + rollupInterval: RollupInterval; }): Promise { const params = { apm: { - events: [ProcessorEvent.metric], + sources: [ + { + documentType, + rollupInterval, + }, + ], }, body: { track_total_hits: false, @@ -78,14 +88,14 @@ export async function getServiceNodeMetadata({ }, }; - const response = await apmEventClient.search( + const { aggregations } = await apmEventClient.search( 'get_service_node_metadata', params ); return { - host: response.aggregations?.host.buckets[0]?.key || NOT_AVAILABLE_LABEL, + host: aggregations?.host.buckets[0]?.key || NOT_AVAILABLE_LABEL, containerId: - response.aggregations?.containerId.buckets[0]?.key || NOT_AVAILABLE_LABEL, + aggregations?.containerId.buckets[0]?.key || NOT_AVAILABLE_LABEL, }; } diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index 24dc79ea668b..0a51a3e88379 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -368,14 +368,20 @@ const serviceNodeMetadataRoute = createApmServerRoute({ serviceName: t.string, serviceNodeName: t.string, }), - query: t.intersection([kueryRt, rangeRt, environmentRt]), + query: t.intersection([ + kueryRt, + rangeRt, + environmentRt, + serviceTransactionDataSourceRt, + ]), }), options: { tags: ['access:apm'] }, handler: async (resources): Promise => { const apmEventClient = await getApmEventClient(resources); const { params } = resources; const { serviceName, serviceNodeName } = params.path; - const { kuery, start, end, environment } = params.query; + const { kuery, start, end, environment, documentType, rollupInterval } = + params.query; return getServiceNodeMetadata({ kuery, @@ -385,6 +391,8 @@ const serviceNodeMetadataRoute = createApmServerRoute({ start, end, environment, + documentType, + rollupInterval, }); }, }); diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/__snapshots__/get_transaction.test.ts.snap b/x-pack/plugins/apm/server/routes/settings/custom_link/__snapshots__/get_transaction.test.ts.snap index 3a738243cf5c..ea8d4318f4c5 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/__snapshots__/get_transaction.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/__snapshots__/get_transaction.test.ts.snap @@ -3,8 +3,11 @@ exports[`custom link get transaction fetches with all filter 1`] = ` Object { "apm": Object { - "events": Array [ - "transaction", + "sources": Array [ + Object { + "documentType": "transactionEvent", + "rollupInterval": "none", + }, ], }, "body": Object { @@ -52,8 +55,11 @@ Object { exports[`custom link get transaction fetches without filter 1`] = ` Object { "apm": Object { - "events": Array [ - "transaction", + "sources": Array [ + Object { + "documentType": "transactionEvent", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts index d454b447b17f..58cdd55b2d44 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/get_transaction.ts @@ -7,7 +7,8 @@ import * as t from 'io-ts'; import { compact } from 'lodash'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; import { filterOptionsRt } from './custom_link_types'; import { splitFilterValueByComma } from './helper'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; @@ -29,10 +30,15 @@ export async function getTransaction({ }) ); - const params = { + const resp = await apmEventClient.search('get_transaction_for_custom_link', { terminate_after: 1, apm: { - events: [ProcessorEvent.transaction as const], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, @@ -43,10 +49,6 @@ export async function getTransaction({ }, }, }, - }; - const resp = await apmEventClient.search( - 'get_transaction_for_custom_link', - params - ); + }); return resp.hits.hits[0]?._source; } diff --git a/x-pack/plugins/apm/server/routes/traces/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/routes/traces/__snapshots__/queries.test.ts.snap index a490aec44a36..d64c33a421e1 100644 --- a/x-pack/plugins/apm/server/routes/traces/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/traces/__snapshots__/queries.test.ts.snap @@ -3,8 +3,11 @@ exports[`trace queries fetches a trace 1`] = ` Object { "apm": Object { - "events": Array [ - "error", + "sources": Array [ + Object { + "documentType": "error", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts b/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts index a1637b29d8e7..3a3e9b8fe295 100644 --- a/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts +++ b/x-pack/plugins/apm/server/routes/traces/get_trace_items.ts @@ -55,6 +55,8 @@ import { } from '../../../common/waterfall/typings'; import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client'; import { getSpanLinksCountById } from '../span_links/get_linked_children'; +import { ApmDocumentType } from '../../../common/document_type'; +import { RollupInterval } from '../../../common/rollup'; export interface TraceItems { exceedsMax: boolean; @@ -87,7 +89,12 @@ export async function getTraceItems({ const errorResponsePromise = apmEventClient.search('get_errors_docs', { apm: { - events: [ProcessorEvent.error], + sources: [ + { + documentType: ApmDocumentType.ErrorEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/apm/server/routes/transactions/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/routes/transactions/__snapshots__/queries.test.ts.snap index 4ff86970a611..deb1dec096f0 100644 --- a/x-pack/plugins/apm/server/routes/transactions/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/transactions/__snapshots__/queries.test.ts.snap @@ -3,8 +3,11 @@ exports[`transaction queries fetches a transaction 1`] = ` Object { "apm": Object { - "events": Array [ - "transaction", + "sources": Array [ + Object { + "documentType": "transactionEvent", + "rollupInterval": "none", + }, ], }, "body": Object { diff --git a/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts b/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts index 77935244361b..8854f3075e59 100644 --- a/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts +++ b/x-pack/plugins/apm/server/routes/transactions/get_transaction/index.ts @@ -6,10 +6,11 @@ */ import { rangeQuery, termQuery } from '@kbn/observability-plugin/server'; -import { ProcessorEvent } from '@kbn/observability-plugin/common'; import { TRACE_ID, TRANSACTION_ID } from '../../../../common/es_fields/apm'; import { asMutableArray } from '../../../../common/utils/as_mutable_array'; import { APMEventClient } from '../../../lib/helpers/create_es_client/create_apm_event_client'; +import { ApmDocumentType } from '../../../../common/document_type'; +import { RollupInterval } from '../../../../common/rollup'; export async function getTransaction({ transactionId, @@ -26,7 +27,12 @@ export async function getTransaction({ }) { const resp = await apmEventClient.search('get_transaction', { apm: { - events: [ProcessorEvent.transaction], + sources: [ + { + documentType: ApmDocumentType.TransactionEvent, + rollupInterval: RollupInterval.None, + }, + ], }, body: { track_total_hits: false, diff --git a/x-pack/plugins/asset_manager/common/constants_routes.ts b/x-pack/plugins/asset_manager/common/constants_routes.ts index 969df93d1bc9..6bbde84cc668 100644 --- a/x-pack/plugins/asset_manager/common/constants_routes.ts +++ b/x-pack/plugins/asset_manager/common/constants_routes.ts @@ -18,3 +18,4 @@ export const GET_ASSETS_DIFF = base('/assets/diff'); export const GET_HOSTS = base('/assets/hosts'); export const GET_SERVICES = base('/assets/services'); export const GET_CONTAINERS = base('/assets/containers'); +export const GET_PODS = base('/assets/pods'); diff --git a/x-pack/plugins/asset_manager/common/types_api.ts b/x-pack/plugins/asset_manager/common/types_api.ts index dd555c69328e..8c6d7cf5fb0a 100644 --- a/x-pack/plugins/asset_manager/common/types_api.ts +++ b/x-pack/plugins/asset_manager/common/types_api.ts @@ -172,6 +172,7 @@ export const assetFiltersSingleKindRT = rt.exact( id: rt.string, ['cloud.provider']: rt.string, ['cloud.region']: rt.string, + ['orchestrator.cluster.name']: rt.string, }) ); @@ -258,3 +259,21 @@ export const getServiceAssetsResponseRT = rt.type({ services: rt.array(assetRT), }); export type GetServiceAssetsResponse = rt.TypeOf; + +/** + * Pods + */ +export const getPodAssetsQueryOptionsRT = rt.intersection([ + rt.strict({ from: assetDateRT }), + rt.partial({ + to: assetDateRT, + size: sizeRT, + stringFilters: rt.string, + filters: assetFiltersSingleKindRT, + }), +]); +export type GetPodAssetsQueryOptions = rt.TypeOf; +export const getPodAssetsResponseRT = rt.type({ + pods: rt.array(assetRT), +}); +export type GetPodAssetsResponse = rt.TypeOf; diff --git a/x-pack/plugins/asset_manager/common/types_client.ts b/x-pack/plugins/asset_manager/common/types_client.ts index 40b3eb5e07e8..5025bbdceed5 100644 --- a/x-pack/plugins/asset_manager/common/types_client.ts +++ b/x-pack/plugins/asset_manager/common/types_client.ts @@ -19,6 +19,7 @@ export interface SharedAssetsOptionsPublic { export type GetHostsOptionsPublic = SharedAssetsOptionsPublic; export type GetContainersOptionsPublic = SharedAssetsOptionsPublic; +export type GetPodsOptionsPublic = SharedAssetsOptionsPublic; export interface GetServicesOptionsPublic extends SharedAssetsOptionsPublic { diff --git a/x-pack/plugins/asset_manager/public/lib/public_assets_client.ts b/x-pack/plugins/asset_manager/public/lib/public_assets_client.ts index 7ff5617d8ceb..2da23c359d4b 100644 --- a/x-pack/plugins/asset_manager/public/lib/public_assets_client.ts +++ b/x-pack/plugins/asset_manager/public/lib/public_assets_client.ts @@ -10,13 +10,15 @@ import { GetContainersOptionsPublic, GetHostsOptionsPublic, GetServicesOptionsPublic, + GetPodsOptionsPublic, } from '../../common/types_client'; import { GetContainerAssetsResponse, GetHostAssetsResponse, GetServiceAssetsResponse, + GetPodAssetsResponse, } from '../../common/types_api'; -import { GET_CONTAINERS, GET_HOSTS, GET_SERVICES } from '../../common/constants_routes'; +import { GET_CONTAINERS, GET_HOSTS, GET_SERVICES, GET_PODS } from '../../common/constants_routes'; import { IPublicAssetsClient } from '../types'; export class PublicAssetsClient implements IPublicAssetsClient { @@ -57,4 +59,16 @@ export class PublicAssetsClient implements IPublicAssetsClient { return results; } + + async getPods(options: GetPodsOptionsPublic) { + const { filters, ...otherOptions } = options; + const results = await this.http.get(GET_PODS, { + query: { + stringFilters: JSON.stringify(filters), + ...otherOptions, + }, + }); + + return results; + } } diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts b/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts index 0a7b34b9ad1a..8a7aad907a36 100644 --- a/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts +++ b/x-pack/plugins/asset_manager/server/lib/accessors/containers/get_containers.test.ts @@ -32,7 +32,7 @@ function createBaseOptions({ }; } -describe('getHosts', () => { +describe('getContainers', () => { let getApmIndicesMock = createGetApmIndicesMock(); let metricsDataClientMock = MetricsDataClientMock.create(); let baseOptions = createBaseOptions({ getApmIndicesMock, metricsDataClientMock }); diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.test.ts b/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.test.ts new file mode 100644 index 000000000000..94d367963588 --- /dev/null +++ b/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.test.ts @@ -0,0 +1,341 @@ +/* + * 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 { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks'; +import { GetApmIndicesMethod } from '../../asset_client_types'; +import { getPods } from './get_pods'; +import { + createGetApmIndicesMock, + expectToThrowValidationErrorWithStatusCode, +} from '../../../test_utils'; +import { MetricsDataClient, MetricsDataClientMock } from '@kbn/metrics-data-access-plugin/server'; +import { SearchRequest } from '@elastic/elasticsearch/lib/api/types'; + +function createBaseOptions({ + getApmIndicesMock, + metricsDataClientMock, +}: { + getApmIndicesMock: GetApmIndicesMethod; + metricsDataClientMock: MetricsDataClient; +}) { + return { + sourceIndices: { + logs: 'my-logs*', + }, + getApmIndices: getApmIndicesMock, + metricsClient: metricsDataClientMock, + }; +} + +describe('getPods', () => { + let getApmIndicesMock = createGetApmIndicesMock(); + let metricsDataClientMock = MetricsDataClientMock.create(); + let baseOptions = createBaseOptions({ getApmIndicesMock, metricsDataClientMock }); + let esClientMock = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + let soClientMock = savedObjectsClientMock.create(); + + function resetMocks() { + getApmIndicesMock = createGetApmIndicesMock(); + metricsDataClientMock = MetricsDataClientMock.create(); + baseOptions = createBaseOptions({ getApmIndicesMock, metricsDataClientMock }); + esClientMock = elasticsearchClientMock.createScopedClusterClient().asCurrentUser; + soClientMock = savedObjectsClientMock.create(); + } + + beforeEach(() => { + resetMocks(); + + // ES returns no results, just enough structure to not blow up + esClientMock.search.mockResolvedValueOnce({ + took: 1, + timed_out: false, + _shards: { + failed: 0, + successful: 1, + total: 1, + }, + hits: { + hits: [], + }, + }); + }); + + it('should query Elasticsearch correctly', async () => { + await getPods({ + ...baseOptions, + from: 'now-5d', + to: 'now-3d', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + }); + + expect(metricsDataClientMock.getMetricIndices).toHaveBeenCalledTimes(1); + expect(metricsDataClientMock.getMetricIndices).toHaveBeenCalledWith({ + savedObjectsClient: soClientMock, + }); + + const dsl = esClientMock.search.mock.lastCall?.[0] as SearchRequest | undefined; + const { bool } = dsl?.query || {}; + expect(bool).toBeDefined(); + + expect(bool?.filter).toEqual([ + { + range: { + '@timestamp': { + gte: 'now-5d', + lte: 'now-3d', + }, + }, + }, + ]); + + expect(bool?.must).toEqual([ + { + exists: { + field: 'kubernetes.pod.uid', + }, + }, + { + exists: { + field: 'kubernetes.node.name', + }, + }, + ]); + }); + + it('should correctly include an EAN filter as a pod ID term query', async () => { + const mockPodId = '123abc'; + + await getPods({ + ...baseOptions, + from: 'now-1h', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + filters: { + ean: `pod:${mockPodId}`, + }, + }); + + const dsl = esClientMock.search.mock.lastCall?.[0] as SearchRequest | undefined; + const { bool } = dsl?.query || {}; + expect(bool).toBeDefined(); + + expect(bool?.must).toEqual( + expect.arrayContaining([ + { + exists: { + field: 'kubernetes.pod.uid', + }, + }, + { + exists: { + field: 'kubernetes.node.name', + }, + }, + { + term: { + 'kubernetes.pod.uid': mockPodId, + }, + }, + ]) + ); + }); + + it('should not query ES and return empty if filtering on non-pod EAN', async () => { + const mockId = 'some-id-123'; + + const result = await getPods({ + ...baseOptions, + from: 'now-1h', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + filters: { + ean: `container:${mockId}`, + }, + }); + + expect(esClientMock.search).toHaveBeenCalledTimes(0); + expect(result).toEqual({ pods: [] }); + }); + + it('should include a wildcard ID filter when an ID filter is provided with asterisks included', async () => { + const mockIdPattern = '*partial-id*'; + + await getPods({ + ...baseOptions, + from: 'now-1h', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + filters: { + id: mockIdPattern, + }, + }); + + const dsl = esClientMock.search.mock.lastCall?.[0] as SearchRequest | undefined; + const { bool } = dsl?.query || {}; + expect(bool).toBeDefined(); + + expect(bool?.must).toEqual( + expect.arrayContaining([ + { + exists: { + field: 'kubernetes.pod.uid', + }, + }, + { + exists: { + field: 'kubernetes.node.name', + }, + }, + { + wildcard: { + 'kubernetes.pod.uid': mockIdPattern, + }, + }, + ]) + ); + }); + + it('should include a term ID filter when an ID filter is provided without asterisks included', async () => { + const mockId = 'full-id'; + + await getPods({ + ...baseOptions, + from: 'now-1h', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + filters: { + id: mockId, + }, + }); + + const dsl = esClientMock.search.mock.lastCall?.[0] as SearchRequest | undefined; + const { bool } = dsl?.query || {}; + expect(bool).toBeDefined(); + + expect(bool?.must).toEqual( + expect.arrayContaining([ + { + exists: { + field: 'kubernetes.pod.uid', + }, + }, + { + exists: { + field: 'kubernetes.node.name', + }, + }, + { + term: { + 'kubernetes.pod.uid': mockId, + }, + }, + ]) + ); + }); + + it('should include a term filter for cloud filters', async () => { + const mockCloudProvider = 'gcp'; + const mockCloudRegion = 'us-central-1'; + + await getPods({ + ...baseOptions, + from: 'now-1h', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + filters: { + 'cloud.provider': mockCloudProvider, + 'cloud.region': mockCloudRegion, + }, + }); + + const dsl = esClientMock.search.mock.lastCall?.[0] as SearchRequest | undefined; + const { bool } = dsl?.query || {}; + expect(bool).toBeDefined(); + + expect(bool?.must).toEqual( + expect.arrayContaining([ + { + exists: { + field: 'kubernetes.pod.uid', + }, + }, + { + exists: { + field: 'kubernetes.node.name', + }, + }, + { + term: { + 'cloud.provider': mockCloudProvider, + }, + }, + { + term: { + 'cloud.region': mockCloudRegion, + }, + }, + ]) + ); + }); + + it('should reject with 400 for invalid "from" date', () => { + return expectToThrowValidationErrorWithStatusCode( + () => + getPods({ + ...baseOptions, + from: 'now-1zz', + to: 'now-3d', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + }), + { statusCode: 400 } + ); + }); + + it('should reject with 400 for invalid "to" date', () => { + return expectToThrowValidationErrorWithStatusCode( + () => + getPods({ + ...baseOptions, + from: 'now-5d', + to: 'now-3fe', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + }), + { statusCode: 400 } + ); + }); + + it('should reject with 400 when "from" is a date that is after "to"', () => { + return expectToThrowValidationErrorWithStatusCode( + () => + getPods({ + ...baseOptions, + from: 'now', + to: 'now-5d', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + }), + { statusCode: 400 } + ); + }); + + it('should reject with 400 when "from" is in the future', () => { + return expectToThrowValidationErrorWithStatusCode( + () => + getPods({ + ...baseOptions, + from: 'now+1d', + elasticsearchClient: esClientMock, + savedObjectsClient: soClientMock, + }), + { statusCode: 400 } + ); + }); +}); diff --git a/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.ts b/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.ts new file mode 100644 index 000000000000..db2bc11ae231 --- /dev/null +++ b/x-pack/plugins/asset_manager/server/lib/accessors/pods/get_pods.ts @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; +import { Asset } from '../../../../common/types_api'; +import { GetPodsOptionsPublic } from '../../../../common/types_client'; +import { + AssetClientDependencies, + AssetClientOptionsWithInjectedValues, +} from '../../asset_client_types'; +import { parseEan } from '../../parse_ean'; +import { collectPods } from '../../collectors/pods'; +import { validateStringDateRange } from '../../validators/validate_date_range'; + +export type GetPodsOptions = GetPodsOptionsPublic & AssetClientDependencies; +export type GetPodsOptionsInjected = AssetClientOptionsWithInjectedValues; + +export async function getPods(options: GetPodsOptionsInjected): Promise<{ pods: Asset[] }> { + validateStringDateRange(options.from, options.to); + + const metricsIndices = await options.metricsClient.getMetricIndices({ + savedObjectsClient: options.savedObjectsClient, + }); + + const filters: QueryDslQueryContainer[] = []; + + if (options.filters?.ean) { + const ean = Array.isArray(options.filters.ean) ? options.filters.ean[0] : options.filters.ean; + const { kind, id } = parseEan(ean); + + // if EAN filter isn't targeting a pod asset, we don't need to do this query + if (kind !== 'pod') { + return { + pods: [], + }; + } + + filters.push({ + term: { + 'kubernetes.pod.uid': id, + }, + }); + } + + if (options.filters?.id) { + const fn = options.filters.id.includes('*') ? 'wildcard' : 'term'; + filters.push({ + [fn]: { + 'kubernetes.pod.uid': options.filters.id, + }, + }); + } + + if (options.filters?.['orchestrator.cluster.name']) { + filters.push({ + term: { + 'orchestrator.cluster.name': options.filters['orchestrator.cluster.name'], + }, + }); + } + + if (options.filters?.['cloud.provider']) { + filters.push({ + term: { + 'cloud.provider': options.filters['cloud.provider'], + }, + }); + } + + if (options.filters?.['cloud.region']) { + filters.push({ + term: { + 'cloud.region': options.filters['cloud.region'], + }, + }); + } + + const { assets } = await collectPods({ + client: options.elasticsearchClient, + from: options.from, + to: options.to || 'now', + filters, + sourceIndices: { + metrics: metricsIndices, + logs: options.sourceIndices.logs, + }, + }); + + return { + pods: assets, + }; +} diff --git a/x-pack/plugins/asset_manager/server/lib/asset_client.ts b/x-pack/plugins/asset_manager/server/lib/asset_client.ts index a7aad8f6a01c..ca6e7f2ea05d 100644 --- a/x-pack/plugins/asset_manager/server/lib/asset_client.ts +++ b/x-pack/plugins/asset_manager/server/lib/asset_client.ts @@ -9,6 +9,7 @@ import { Asset } from '../../common/types_api'; import { getContainers, GetContainersOptions } from './accessors/containers/get_containers'; import { getHosts, GetHostsOptions } from './accessors/hosts/get_hosts'; import { getServices, GetServicesOptions } from './accessors/services/get_services'; +import { getPods, GetPodsOptions } from './accessors/pods/get_pods'; import { AssetClientBaseOptions, AssetClientOptionsWithInjectedValues } from './asset_client_types'; export class AssetClient { @@ -35,4 +36,9 @@ export class AssetClient { const withInjected = this.injectOptions(options); return await getContainers(withInjected); } + + async getPods(options: GetPodsOptions): Promise<{ pods: Asset[] }> { + const withInjected = this.injectOptions(options); + return await getPods(withInjected); + } } diff --git a/x-pack/plugins/asset_manager/server/lib/collectors/pods.ts b/x-pack/plugins/asset_manager/server/lib/collectors/pods.ts index 5cbf357e6956..f9a4e2e22ae5 100644 --- a/x-pack/plugins/asset_manager/server/lib/collectors/pods.ts +++ b/x-pack/plugins/asset_manager/server/lib/collectors/pods.ts @@ -9,11 +9,24 @@ import { estypes } from '@elastic/elasticsearch'; import { Asset } from '../../../common/types_api'; import { CollectorOptions, QUERY_MAX_SIZE } from '.'; -export async function collectPods({ client, from, to, sourceIndices, afterKey }: CollectorOptions) { +export async function collectPods({ + client, + from, + to, + sourceIndices, + filters = [], + afterKey, +}: CollectorOptions) { if (!sourceIndices?.metrics || !sourceIndices?.logs) { throw new Error('missing required metrics/logs indices'); } + const musts = [ + ...filters, + { exists: { field: 'kubernetes.pod.uid' } }, + { exists: { field: 'kubernetes.node.name' } }, + ]; + const { metrics, logs } = sourceIndices; const dsl: estypes.SearchRequest = { index: [metrics, logs], @@ -42,10 +55,7 @@ export async function collectPods({ client, from, to, sourceIndices, afterKey }: }, }, ], - must: [ - { exists: { field: 'kubernetes.pod.uid' } }, - { exists: { field: 'kubernetes.node.name' } }, - ], + must: musts, }, }, }; diff --git a/x-pack/plugins/asset_manager/server/routes/assets/pods.ts b/x-pack/plugins/asset_manager/server/routes/assets/pods.ts new file mode 100644 index 000000000000..beed936bd5b4 --- /dev/null +++ b/x-pack/plugins/asset_manager/server/routes/assets/pods.ts @@ -0,0 +1,70 @@ +/* + * 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 { createRouteValidationFunction } from '@kbn/io-ts-utils'; +import { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; +import { GetPodAssetsQueryOptions, getPodAssetsQueryOptionsRT } from '../../../common/types_api'; +import { debug } from '../../../common/debug_log'; +import { SetupRouteOptions } from '../types'; +import * as routePaths from '../../../common/constants_routes'; +import { getClientsFromContext, validateStringAssetFilters } from '../utils'; +import { AssetsValidationError } from '../../lib/validators/validation_error'; + +export function podsRoutes({ + router, + assetClient, +}: SetupRouteOptions) { + const validate = createRouteValidationFunction(getPodAssetsQueryOptionsRT); + router.get( + { + path: routePaths.GET_PODS, + validate: { + query: (q, res) => { + const [invalidResponse, validatedFilters] = validateStringAssetFilters(q, res); + if (invalidResponse) { + return invalidResponse; + } + if (validatedFilters) { + q.filters = validatedFilters; + } + return validate(q, res); + }, + }, + }, + async (context, req, res) => { + const { from = 'now-24h', to = 'now', filters } = req.query || {}; + const { elasticsearchClient, savedObjectsClient } = await getClientsFromContext(context); + + try { + const response = await assetClient.getPods({ + from, + to, + filters, + elasticsearchClient, + savedObjectsClient, + }); + + return res.ok({ body: response }); + } catch (error: unknown) { + debug('Error while looking up POD asset records', error); + + if (error instanceof AssetsValidationError) { + return res.customError({ + statusCode: error.statusCode, + body: { + message: `Error while looking up pod asset records - ${error.message}`, + }, + }); + } + return res.customError({ + statusCode: 500, + body: { message: 'Error while looking up pod asset records - ' + `${error}` }, + }); + } + } + ); +} diff --git a/x-pack/plugins/asset_manager/server/routes/index.ts b/x-pack/plugins/asset_manager/server/routes/index.ts index 20f5abf889e7..991c96806b76 100644 --- a/x-pack/plugins/asset_manager/server/routes/index.ts +++ b/x-pack/plugins/asset_manager/server/routes/index.ts @@ -12,6 +12,7 @@ import { sampleAssetsRoutes } from './sample_assets'; import { hostsRoutes } from './assets/hosts'; import { servicesRoutes } from './assets/services'; import { containersRoutes } from './assets/containers'; +import { podsRoutes } from './assets/pods'; export function setupRoutes({ router, @@ -22,4 +23,5 @@ export function setupRoutes({ hostsRoutes({ router, assetClient }); servicesRoutes({ router, assetClient }); containersRoutes({ router, assetClient }); + podsRoutes({ router, assetClient }); } diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx index 915676b8f6b5..f12a805cf18a 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/__stories__/editor_menu.stories.tsx @@ -70,8 +70,10 @@ const testVisTypes: BaseVisType[] = [ const testVisTypeAliases: VisTypeAlias[] = [ { title: 'Lens', - aliasApp: 'lens', - aliasPath: 'path/to/lens', + alias: { + app: 'lens', + path: 'path/to/lens', + }, icon: 'lensApp', name: 'lens', description: 'Description of Lens app', @@ -79,8 +81,10 @@ const testVisTypeAliases: VisTypeAlias[] = [ }, { title: 'Maps', - aliasApp: 'maps', - aliasPath: 'path/to/maps', + alias: { + app: 'maps', + path: 'path/to/maps', + }, icon: 'gisApp', name: 'maps', description: 'Description of Maps app', diff --git a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx index dbcd3b9cd278..d405a977affd 100644 --- a/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_header/editor_menu/editor_menu.tsx @@ -68,12 +68,14 @@ export const EditorMenu: FC = ({ addElement }) => { trackCanvasUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`); } - if ('aliasPath' in visType) { - appId = visType.aliasApp; - path = visType.aliasPath; - } else { + if (!('alias' in visType)) { + // this visualization is not an alias appId = 'visualize'; path = `#/create?type=${encodeURIComponent(visType.name)}`; + } else if (visType.alias && 'path' in visType.alias) { + // this visualization **is** an alias, and it has an app to redirect to for creation + appId = visType.alias.app; + path = visType.alias.path; } } else { appId = 'visualize'; @@ -134,7 +136,8 @@ export const EditorMenu: FC = ({ addElement }) => { .getAliases() .sort(({ promotion: a = false }: VisTypeAlias, { promotion: b = false }: VisTypeAlias) => a === b ? 0 : a ? -1 : 1 - ); + ) + .filter(({ disableCreate }: VisTypeAlias) => !disableCreate); const factories = unwrappedEmbeddableFactories .filter( diff --git a/x-pack/plugins/cases/docs/openapi/bundled.json b/x-pack/plugins/cases/docs/openapi/bundled.json index 54a9c31d3431..bf6b28c8441a 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.json +++ b/x-pack/plugins/cases/docs/openapi/bundled.json @@ -1,9 +1,9 @@ { - "openapi": "3.0.1", + "openapi": "3.1.0", "info": { "title": "Cases", "description": "OpenAPI schema for Cases endpoints", - "version": "0.1", + "version": "0.2", "contact": { "name": "Cases Team" }, @@ -329,7 +329,7 @@ } } }, - "example": [ + "examples": [ { "id": "06116b80-e1c3-11ec-be9b-9b1838238ee6", "title": "security_case" @@ -417,18 +417,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -438,7 +444,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -449,34 +457,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -485,15 +513,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -502,13 +536,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -516,30 +557,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } } @@ -640,18 +696,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -661,7 +723,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -672,34 +736,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -708,15 +792,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -725,13 +815,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -739,30 +836,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } }, @@ -867,18 +979,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -888,7 +1006,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -899,34 +1019,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -935,15 +1075,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -952,13 +1098,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -966,30 +1119,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } }, @@ -1044,23 +1212,37 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } } @@ -1569,8 +1751,10 @@ "content": { "application/json": { "schema": { - "type": "object", - "nullable": true + "type": [ + "object", + "null" + ] } } } @@ -2103,7 +2287,7 @@ } } }, - "example": [ + "examples": [ { "id": "06116b80-e1c3-11ec-be9b-9b1838238ee6", "title": "security_case" @@ -2194,18 +2378,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -2215,7 +2405,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -2226,34 +2418,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -2262,15 +2474,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -2279,13 +2497,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -2293,30 +2518,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } } @@ -2420,18 +2660,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -2441,7 +2687,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -2452,34 +2700,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -2488,15 +2756,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -2505,13 +2779,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -2519,30 +2800,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } }, @@ -2650,18 +2946,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -2671,7 +2973,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-06-01T17:07:17.767Z" + "examples": [ + "2022-06-01T17:07:17.767Z" + ] }, "created_by": { "type": "object", @@ -2682,34 +2986,54 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "error": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "type": "string", - "example": "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + "examples": [ + "4a97a440-e1cd-11ec-be9b-9b1838238ee6" + ] }, "mappings": { "type": "array", @@ -2718,15 +3042,21 @@ "properties": { "action_type": { "type": "string", - "example": "overwrite" + "examples": [ + "overwrite" + ] }, "source": { "type": "string", - "example": "title" + "examples": [ + "title" + ] }, "target": { "type": "string", - "example": "summary" + "examples": [ + "summary" + ] } } } @@ -2735,13 +3065,20 @@ "$ref": "#/components/schemas/owners" }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": "2022-06-01T19:58:48.169Z" + "examples": [ + "2022-06-01T19:58:48.169Z" + ] }, "updated_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -2749,30 +3086,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "version": { "type": "string", - "example": "WzIwNzMsMV0=" + "examples": [ + "WzIwNzMsMV0=" + ] } } }, @@ -2909,23 +3261,37 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } } @@ -3515,8 +3881,10 @@ "content": { "application/json": { "schema": { - "type": "object", - "nullable": true + "type": [ + "object", + "null" + ] } } } @@ -3610,8 +3978,7 @@ "$ref": "#/components/parameters/space_id" }, { - "$ref": "#/components/parameters/page_index", - "example": "1" + "$ref": "#/components/parameters/page_index" }, { "$ref": "#/components/parameters/page_size" @@ -3679,7 +4046,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "parameters": { @@ -3703,9 +4071,13 @@ "type": "string", "minItems": 1, "maxItems": 100 - } - }, - "example": "d4e7abb0-b462-11ec-9a8d-698504725a43" + }, + "examples": [ + [ + "d4e7abb0-b462-11ec-9a8d-698504725a43" + ] + ] + } }, "assignees": { "in": "query", @@ -3740,11 +4112,15 @@ "items": { "type": "string" }, - "maxItems": 100 + "maxItems": 100, + "examples": [ + [ + "my-category" + ] + ] } ] - }, - "example": "my-category" + } }, "defaultSearchOperator": { "in": "query", @@ -3752,9 +4128,11 @@ "description": "he default operator to use for the simple_query_string.", "schema": { "type": "string", - "default": "OR" - }, - "example": "OR" + "default": "OR", + "examples": [ + "OR" + ] + } }, "from": { "in": "query", @@ -3762,7 +4140,9 @@ "description": "Returns only cases that were created after a specific date. The date must be specified as a KQL data range or date match expression.\n", "schema": { "type": "string", - "example": "now-1d" + "examples": [ + "now-1d" + ] } }, "owner": { @@ -3778,11 +4158,15 @@ "type": "array", "items": { "$ref": "#/components/schemas/owners" - } + }, + "examples": [ + [ + "cases" + ] + ] } ] - }, - "example": "cases" + } }, "page_index": { "in": "query", @@ -3791,7 +4175,10 @@ "required": false, "schema": { "type": "integer", - "default": 1 + "default": 1, + "examples": [ + 1 + ] } }, "page_size": { @@ -3819,11 +4206,15 @@ "items": { "type": "string" }, - "maxItems": 100 + "maxItems": 100, + "examples": [ + [ + "elastic" + ] + ] } ] - }, - "example": "elastic" + } }, "search": { "in": "query", @@ -3880,9 +4271,11 @@ "status", "severity" ], - "default": "createdAt" - }, - "example": "updatedAt" + "default": "createdAt", + "examples": [ + "updatedAt" + ] + } }, "sort_order": { "in": "query", @@ -3908,9 +4301,11 @@ "closed", "in-progress", "open" + ], + "examples": [ + "open" ] - }, - "example": "open" + } }, "tags": { "in": "query", @@ -3926,20 +4321,26 @@ "items": { "type": "string" }, - "maxItems": 100 + "maxItems": 100, + "examples": [ + [ + "tag-1" + ] + ] } ] - }, - "example": "tag-1" + } }, "to": { "in": "query", "name": "to", "description": "Returns only cases that were created before a specific date. The date must be specified as a KQL data range or date match expression.\n", "schema": { - "type": "string" - }, - "example": "now+1d" + "type": "string", + "examples": [ + "now+1d" + ] + } }, "alert_id": { "in": "path", @@ -3948,7 +4349,9 @@ "required": true, "schema": { "type": "string", - "example": "09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540" + "examples": [ + "09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540" + ] } }, "configuration_id": { @@ -3958,7 +4361,9 @@ "required": true, "schema": { "type": "string", - "example": "3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9" + "examples": [ + "3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9" + ] } }, "case_id": { @@ -3968,7 +4373,9 @@ "required": true, "schema": { "type": "string", - "example": "9c235210-6834-11ea-a78c-6ffb38a34414" + "examples": [ + "9c235210-6834-11ea-a78c-6ffb38a34414" + ] } }, "includeComments": { @@ -3988,7 +4395,9 @@ "required": true, "schema": { "type": "string", - "example": "71ec1870-725b-11ea-a0b2-c51ea50a58e2" + "examples": [ + "71ec1870-725b-11ea-a0b2-c51ea50a58e2" + ] } }, "connector_id": { @@ -3998,7 +4407,9 @@ "required": true, "schema": { "type": "string", - "example": "abed3a70-71bd-11ea-a0b2-c51ea50a58e2" + "examples": [ + "abed3a70-71bd-11ea-a0b2-c51ea50a58e2" + ] } }, "user_action_types": { @@ -4026,9 +4437,13 @@ "title", "user" ] - } - }, - "example": "create_case" + }, + "examples": [ + [ + "create_case" + ] + ] + } }, "space_id": { "in": "path", @@ -4037,16 +4452,20 @@ "required": true, "schema": { "type": "string", - "example": "default" + "examples": [ + "default" + ] } } }, "schemas": { "assignees": { - "type": "array", + "type": [ + "array", + "null" + ], "description": "An array containing users that are assigned to the case.", "maxItems": 10, - "nullable": true, "items": { "type": "object", "required": [ @@ -4056,7 +4475,9 @@ "uid": { "type": "string", "description": "A unique identifier for the user profile. These identifiers can be found by using the suggest user profile API.", - "example": "u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0" + "examples": [ + "u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0" + ] } } } @@ -4074,24 +4495,34 @@ "properties": { "fields": { "description": "An object containing the connector fields. To create a case without a connector, specify null. To update a case to remove the connector, specify null.", - "nullable": true, - "type": "string", - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "description": "The identifier for the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "description": "The type of connector. To create a case without a connector, use `.none`. To update a case to remove the connector, specify `.none`.", "type": "string", - "example": ".none", + "examples": [ + ".none" + ], "enum": [ ".none" ] @@ -4110,9 +4541,13 @@ "type": "object", "properties": { "fields": { - "type": "string", - "nullable": true, - "example": null + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "id": { "description": "The identifier for the connector. To retrieve connector IDs, use the find connectors API.", @@ -4125,7 +4560,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".cases-webhook", + "examples": [ + ".cases-webhook" + ], "enum": [ ".cases-webhook" ] @@ -4154,18 +4591,24 @@ "properties": { "issueType": { "description": "The type of issue.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "parent": { "description": "The key of the parent issue, when the issue type is sub-task.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "priority": { "description": "The priority of the issue.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -4180,7 +4623,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".jira", + "examples": [ + ".jira" + ], "enum": [ ".jira" ] @@ -4200,8 +4645,10 @@ "properties": { "fields": { "description": "An object containing the connector fields. If you want to omit any individual field, specify null as its value.", - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "required": [ "issueTypes", "severityCode" @@ -4231,7 +4678,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".resilient", + "examples": [ + ".resilient" + ], "enum": [ ".resilient" ] @@ -4262,28 +4711,38 @@ "properties": { "category": { "description": "The category of the incident.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "impact": { "description": "The effect an incident had on business.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "severity": { "description": "The severity of the incident.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "subcategory": { "description": "The subcategory of the incident.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "urgency": { "description": "The extent to which the incident resolution can be delayed.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -4298,7 +4757,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".servicenow", + "examples": [ + ".servicenow" + ], "enum": [ ".servicenow" ] @@ -4331,38 +4792,52 @@ "properties": { "category": { "description": "The category of the incident.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "destIp": { "description": "Indicates whether cases will send a comma-separated list of destination IPs.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "malwareHash": { "description": "Indicates whether cases will send a comma-separated list of malware hashes.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "malwareUrl": { "description": "Indicates whether cases will send a comma-separated list of malware URLs.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "priority": { "description": "The priority of the issue.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] }, "sourceIp": { "description": "Indicates whether cases will send a comma-separated list of source IPs.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "subcategory": { "description": "The subcategory of the incident.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -4377,7 +4852,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".servicenow-sir", + "examples": [ + ".servicenow-sir" + ], "enum": [ ".servicenow-sir" ] @@ -4404,8 +4881,10 @@ "properties": { "caseId": { "description": "The case identifier for Swimlane connectors.", - "type": "string", - "nullable": true + "type": [ + "string", + "null" + ] } } }, @@ -4420,7 +4899,9 @@ "type": { "description": "The type of connector.", "type": "string", - "example": ".swimlane", + "examples": [ + ".swimlane" + ], "enum": [ ".swimlane" ] @@ -4435,7 +4916,9 @@ "observability", "securitySolution" ], - "example": "cases" + "examples": [ + "cases" + ] }, "settings": { "type": "object", @@ -4447,7 +4930,9 @@ "syncAlerts": { "description": "Turns alert syncing on or off.", "type": "boolean", - "example": true + "examples": [ + true + ] } } }, @@ -4566,10 +5051,12 @@ "description": "The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`.\n", "oneOf": [ { - "type": "string", + "type": [ + "string", + "null" + ], "minLength": 1, - "maxLength": 160, - "nullable": true + "maxLength": 160 }, { "type": "boolean" @@ -4583,27 +5070,43 @@ }, "case_response_closed_by_properties": { "title": "Case response properties for closed_by", - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -4623,13 +5126,17 @@ "type": "array", "items": { "type": "string", - "example": "a6e12ac4-7bce-457b-84f6-d7ce8deb8446" + "examples": [ + "a6e12ac4-7bce-457b-84f6-d7ce8deb8446" + ] } }, "created_at": { "type": "string", "format": "date-time", - "example": "2023-11-06T19:29:38.424Z" + "examples": [ + "2023-11-06T19:29:38.424Z" + ] }, "created_by": { "type": "object", @@ -4640,48 +5147,73 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "id": { "type": "string", - "example": "73362370-ab1a-11ec-985f-97e55adae8b9" + "examples": [ + "73362370-ab1a-11ec-985f-97e55adae8b9" + ] }, "index": { "type": "array", "items": { "type": "string", - "example": ".internal.alerts-security.alerts-default-000001" + "examples": [ + ".internal.alerts-security.alerts-default-000001" + ] } }, "owner": { "$ref": "#/components/schemas/owners" }, "pushed_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "example": null, - "nullable": true + "examples": [ + null + ] }, "pushed_by": { - "type": "object", + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -4689,26 +5221,39 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } }, "rule": { "type": "object", @@ -4716,30 +5261,40 @@ "id": { "description": "The rule identifier.", "type": "string", - "example": "94d80550-aaf4-11ec-985f-97e55adae8b9" + "examples": [ + "94d80550-aaf4-11ec-985f-97e55adae8b9" + ] }, "name": { "description": "The rule name.", "type": "string", - "example": "security_rule" + "examples": [ + "security_rule" + ] } } }, "type": { "type": "string", - "example": "alert", + "examples": [ + "alert" + ], "enum": [ "alert" ] }, "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true + "type": [ + "string", + "null" + ], + "format": "date-time" }, "updated_by": { - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "required": [ "email", "full_name", @@ -4747,29 +5302,45 @@ ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } } }, "version": { "type": "string", - "example": "WzMwNDgsMV0=" + "examples": [ + "WzMwNDgsMV0=" + ] } } }, @@ -4778,23 +5349,37 @@ "type": "object", "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -4805,27 +5390,43 @@ }, "case_response_pushed_by_properties": { "title": "Case response properties for pushed_by", - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -4836,27 +5437,43 @@ }, "case_response_updated_by_properties": { "title": "Case response properties for updated_by", - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -4874,57 +5491,77 @@ "properties": { "comment": { "type": "string", - "example": "A new comment." + "examples": [ + "A new comment." + ] }, "created_at": { "type": "string", "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" + "examples": [ + "2022-05-13T09:16:17.416Z" + ] }, "created_by": { "$ref": "#/components/schemas/case_response_created_by_properties" }, "id": { "type": "string", - "example": "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + "examples": [ + "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + ] }, "owner": { "$ref": "#/components/schemas/owners" }, "pushed_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": null + "examples": [ + null + ] }, "pushed_by": { "$ref": "#/components/schemas/case_response_pushed_by_properties" }, "type": { "type": "string", - "example": "user", + "examples": [ + "user" + ], "enum": [ "user" ] }, "updated_at": { - "type": "string", + "type": [ + "string", + "null" + ], "format": "date-time", - "nullable": true, - "example": null + "examples": [ + null + ] }, "updated_by": { "$ref": "#/components/schemas/case_response_updated_by_properties" }, "version": { "type": "string", - "example": "WzIwNDMxLDFd" + "examples": [ + "WzIwNDMxLDFd" + ] } } }, "external_service": { - "type": "object", - "nullable": true, + "type": [ + "object", + "null" + ], "properties": { "connector_id": { "type": "string" @@ -4946,29 +5583,45 @@ "format": "date-time" }, "pushed_by": { - "type": "object", + "type": [ + "object", + "null" + ], "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } - }, - "nullable": true + } } } }, @@ -5012,14 +5665,18 @@ "$ref": "#/components/schemas/assignees" }, "category": { - "type": "string", - "description": "The case category.", - "nullable": true + "type": [ + "string", + "null" + ], + "description": "The case category." }, "closed_at": { - "type": "string", - "format": "date-time", - "nullable": true + "type": [ + "string", + "null" + ], + "format": "date-time" }, "closed_by": { "$ref": "#/components/schemas/case_response_closed_by_properties" @@ -5075,7 +5732,9 @@ "created_at": { "type": "string", "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" + "examples": [ + "2022-05-13T09:16:17.416Z" + ] }, "created_by": { "$ref": "#/components/schemas/case_response_created_by_properties" @@ -5103,10 +5762,12 @@ "description": "The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`.\n", "oneOf": [ { - "type": "string", + "type": [ + "string", + "null" + ], "minLength": 1, - "maxLength": 160, - "nullable": true + "maxLength": 160 }, { "type": "boolean" @@ -5118,20 +5779,28 @@ }, "description": { "type": "string", - "example": "A case description." + "examples": [ + "A case description." + ] }, "duration": { - "type": "integer", + "type": [ + "integer", + "null" + ], "description": "The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero.\n", - "nullable": true, - "example": 120 + "examples": [ + 120 + ] }, "external_service": { "$ref": "#/components/schemas/external_service" }, "id": { "type": "string", - "example": "66b9aa00-94fa-11ea-9f74-e7e108796192" + "examples": [ + "66b9aa00-94fa-11ea-9f74-e7e108796192" + ] }, "owner": { "$ref": "#/components/schemas/owners" @@ -5150,33 +5819,45 @@ "items": { "type": "string" }, - "example": [ - "tag-1" + "examples": [ + [ + "tag-1" + ] ] }, "title": { "type": "string", - "example": "Case title 1" + "examples": [ + "Case title 1" + ] }, "totalAlerts": { "type": "integer", - "example": 0 + "examples": [ + 0 + ] }, "totalComment": { "type": "integer", - "example": 0 + "examples": [ + 0 + ] }, "updated_at": { - "type": "string", - "format": "date-time", - "nullable": true + "type": [ + "string", + "null" + ], + "format": "date-time" }, "updated_by": { "$ref": "#/components/schemas/case_response_updated_by_properties" }, "version": { "type": "string", - "example": "WzUzMiwxXQ==" + "examples": [ + "WzUzMiwxXQ==" + ] } } }, @@ -5186,14 +5867,18 @@ "properties": { "error": { "type": "string", - "example": "Unauthorized" + "examples": [ + "Unauthorized" + ] }, "message": { "type": "string" }, "statusCode": { "type": "integer", - "example": 401 + "examples": [ + 401 + ] } } }, @@ -5280,10 +5965,12 @@ "description": "The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`.\n", "oneOf": [ { - "type": "string", + "type": [ + "string", + "null" + ], "minLength": 1, - "maxLength": 160, - "nullable": true + "maxLength": 160 }, { "type": "boolean" @@ -5349,7 +6036,9 @@ "close-by-pushing", "close-by-user" ], - "example": "close-by-user" + "examples": [ + "close-by-user" + ] }, "connector_types": { "type": "string", @@ -5363,7 +6052,9 @@ ".servicenow-sir", ".swimlane" ], - "example": ".none" + "examples": [ + ".none" + ] }, "set_case_configuration_request": { "title": "Set case configuration request", @@ -5384,18 +6075,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -5472,18 +6169,24 @@ "properties": { "fields": { "description": "The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`.", - "nullable": true, - "type": "object" + "type": [ + "object", + "null" + ] }, "id": { "description": "The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -5539,7 +6242,9 @@ "version": { "description": "The version of the connector. To retrieve the version value, use the get configuration API.\n", "type": "string", - "example": "WzIwMiwxXQ==" + "examples": [ + "WzIwMiwxXQ==" + ] } } }, @@ -5576,7 +6281,9 @@ } ], "x-technical-preview": true, - "example": "6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42" + "examples": [ + "6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42" + ] }, "alert_indices": { "title": "Alert indices", @@ -5604,12 +6311,16 @@ "id": { "description": "The rule identifier.", "type": "string", - "example": "94d80550-aaf4-11ec-985f-97e55adae8b9" + "examples": [ + "94d80550-aaf4-11ec-985f-97e55adae8b9" + ] }, "name": { "description": "The rule name.", "type": "string", - "example": "security_rule" + "examples": [ + "security_rule" + ] } } }, @@ -5640,7 +6351,9 @@ "type": { "description": "The type of comment.", "type": "string", - "example": "alert", + "examples": [ + "alert" + ], "enum": [ "alert" ] @@ -5656,7 +6369,9 @@ "description": "The new comment. It is required only when `type` is `user`.", "type": "string", "maxLength": 30000, - "example": "A new comment." + "examples": [ + "A new comment." + ] }, "owner": { "$ref": "#/components/schemas/owners" @@ -5664,7 +6379,9 @@ "type": { "type": "string", "description": "The type of comment.", - "example": "user", + "examples": [ + "user" + ], "enum": [ "user" ] @@ -5711,7 +6428,9 @@ "id": { "type": "string", "description": "The identifier for the comment. To retrieve comment IDs, use the get comments API.\n", - "example": "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + "examples": [ + "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + ] }, "index": { "$ref": "#/components/schemas/alert_indices" @@ -5728,12 +6447,16 @@ "enum": [ "alert" ], - "example": "alert" + "examples": [ + "alert" + ] }, "version": { "description": "The current comment version. To retrieve version values, use the get comments API.\n", "type": "string", - "example": "Wzk1LDFd" + "examples": [ + "Wzk1LDFd" + ] } } }, @@ -5746,12 +6469,16 @@ "description": "The new comment. It is required only when `type` is `user`.", "type": "string", "maxLength": 30000, - "example": "A new comment." + "examples": [ + "A new comment." + ] }, "id": { "type": "string", "description": "The identifier for the comment. To retrieve comment IDs, use the get comments API.\n", - "example": "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + "examples": [ + "8af6ac20-74f6-11ea-b83a-553aecdb28b6" + ] }, "owner": { "$ref": "#/components/schemas/owners" @@ -5762,12 +6489,16 @@ "enum": [ "user" ], - "example": "user" + "examples": [ + "user" + ] }, "version": { "description": "The current comment version. To retrieve version values, use the get comments API.\n", "type": "string", - "example": "Wzk1LDFd" + "examples": [ + "Wzk1LDFd" + ] } }, "required": [ @@ -5802,7 +6533,9 @@ "push_to_service", "update" ], - "example": "create" + "examples": [ + "create" + ] }, "payload_alert_comment": { "type": "object", @@ -5814,7 +6547,9 @@ "oneOf": [ { "type": "string", - "example": "1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d" + "examples": [ + "1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d" + ] }, { "type": "array", @@ -5828,7 +6563,9 @@ "oneOf": [ { "type": "string", - "example": ".alerts-observability.logs.alerts-default" + "examples": [ + ".alerts-observability.logs.alerts-default" + ] }, { "type": "array", @@ -5847,12 +6584,16 @@ "id": { "description": "The rule identifier.", "type": "string", - "example": "94d80550-aaf4-11ec-985f-97e55adae8b9" + "examples": [ + "94d80550-aaf4-11ec-985f-97e55adae8b9" + ] }, "name": { "description": "The rule name.", "type": "string", - "example": "security_rule" + "examples": [ + "security_rule" + ] } } }, @@ -5881,9 +6622,11 @@ "type": "object", "properties": { "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", + "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.\n", + "type": [ + "object", + "null" + ], "properties": { "caseId": { "description": "The case identifier for Swimlane connectors.", @@ -5895,8 +6638,10 @@ }, "destIp": { "description": "Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "impact": { "description": "The effect an incident had on business for ServiceNow ITSM connectors.", @@ -5915,13 +6660,17 @@ }, "malwareHash": { "description": "Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "malwareUrl": { "description": "Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "parent": { "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", @@ -5941,8 +6690,10 @@ }, "sourceIp": { "description": "Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "subcategory": { "description": "The subcategory of the incident for ServiceNow ITSM connectors.", @@ -5953,17 +6704,23 @@ "type": "string" } }, - "example": null + "examples": [ + null + ] }, "id": { "description": "The identifier for the connector. To create a case without a connector, use `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. To create a case without a connector, use `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -5982,9 +6739,11 @@ "type": "object", "properties": { "fields": { - "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.", - "nullable": true, - "type": "object", + "description": "An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value.\n", + "type": [ + "object", + "null" + ], "properties": { "caseId": { "description": "The case identifier for Swimlane connectors.", @@ -5996,8 +6755,10 @@ }, "destIp": { "description": "Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "impact": { "description": "The effect an incident had on business for ServiceNow ITSM connectors.", @@ -6016,13 +6777,17 @@ }, "malwareHash": { "description": "Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "malwareUrl": { "description": "Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "parent": { "description": "The key of the parent issue, when the issue type is sub-task for Jira connectors.", @@ -6042,8 +6807,10 @@ }, "sourceIp": { "description": "Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors.", - "type": "boolean", - "nullable": true + "type": [ + "boolean", + "null" + ] }, "subcategory": { "description": "The subcategory of the incident for ServiceNow ITSM connectors.", @@ -6054,17 +6821,23 @@ "type": "string" } }, - "example": null + "examples": [ + null + ] }, "id": { "description": "The identifier for the connector. To create a case without a connector, use `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "name": { "description": "The name of the connector. To create a case without a connector, use `none`.", "type": "string", - "example": "none" + "examples": [ + "none" + ] }, "type": { "$ref": "#/components/schemas/connector_types" @@ -6089,11 +6862,13 @@ "tags": { "type": "array", "items": { - "type": "string", - "example": [ + "type": "string" + }, + "examples": [ + [ "tag-1" ] - } + ] }, "title": { "type": "string" @@ -6101,9 +6876,11 @@ } }, "payload_delete": { - "type": "object", - "description": "If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable.", - "nullable": true + "type": [ + "object", + "null" + ], + "description": "If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable." }, "payload_description": { "type": "object", @@ -6153,8 +6930,10 @@ "items": { "type": "string" }, - "example": [ - "tag-1" + "examples": [ + [ + "tag-1" + ] ] } } @@ -6206,7 +6985,9 @@ "settings", "severity" ], - "example": "create_case" + "examples": [ + "create_case" + ] }, "user_actions_response_properties": { "type": "object", @@ -6227,43 +7008,67 @@ }, "action_id": { "type": "string", - "example": "22fd3e30-03b1-11ed-920c-974bfa104448" + "examples": [ + "22fd3e30-03b1-11ed-920c-974bfa104448" + ] }, "case_id": { "type": "string", - "example": "22df07d0-03b1-11ed-920c-974bfa104448" + "examples": [ + "22df07d0-03b1-11ed-920c-974bfa104448" + ] }, "comment_id": { - "type": "string", - "nullable": true, - "example": "578608d0-03b1-11ed-920c-974bfa104448" + "type": [ + "string", + "null" + ], + "examples": [ + "578608d0-03b1-11ed-920c-974bfa104448" + ] }, "created_at": { "type": "string", "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" + "examples": [ + "2022-05-13T09:16:17.416Z" + ] }, "created_by": { "type": "object", "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -6341,36 +7146,56 @@ "$ref": "#/components/schemas/actions" }, "comment_id": { - "type": "string", - "nullable": true, - "example": "578608d0-03b1-11ed-920c-974bfa104448" + "type": [ + "string", + "null" + ], + "examples": [ + "578608d0-03b1-11ed-920c-974bfa104448" + ] }, "created_at": { "type": "string", "format": "date-time", - "example": "2022-05-13T09:16:17.416Z" + "examples": [ + "2022-05-13T09:16:17.416Z" + ] }, "created_by": { "type": "object", "properties": { "email": { - "type": "string", - "example": null, - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "full_name": { - "type": "string", - "example": null, - "nullable": true - }, - "username": { - "type": "string", - "example": "elastic", - "nullable": true + "type": [ + "string", + "null" + ], + "examples": [ + null + ] }, "profile_uid": { "type": "string", - "example": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + "examples": [ + "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" + ] + }, + "username": { + "type": [ + "string", + "null" + ], + "examples": [ + "elastic" + ] } }, "required": [ @@ -6381,7 +7206,9 @@ }, "id": { "type": "string", - "example": "22fd3e30-03b1-11ed-920c-974bfa104448" + "examples": [ + "22fd3e30-03b1-11ed-920c-974bfa104448" + ] }, "owner": { "$ref": "#/components/schemas/owners" @@ -6431,7 +7258,9 @@ }, "version": { "type": "string", - "example": "WzM1ODg4LDFd" + "examples": [ + "WzM1ODg4LDFd" + ] }, "type": { "type": "string", @@ -6449,7 +7278,9 @@ "settings", "severity" ], - "example": "create_case" + "examples": [ + "create_case" + ] } } } diff --git a/x-pack/plugins/cases/docs/openapi/bundled.yaml b/x-pack/plugins/cases/docs/openapi/bundled.yaml index 8347d7d85741..e837ef766ab0 100644 --- a/x-pack/plugins/cases/docs/openapi/bundled.yaml +++ b/x-pack/plugins/cases/docs/openapi/bundled.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Cases description: OpenAPI schema for Cases endpoints - version: '0.1' + version: '0.2' contact: name: Cases Team license: @@ -194,7 +194,7 @@ paths: title: type: string description: The case title. - example: + examples: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case '401': @@ -258,22 +258,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -282,27 +286,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -310,46 +324,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: getConfigurationResponse: $ref: '#/components/examples/get_case_configuration_response' @@ -419,22 +447,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -443,27 +475,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -471,46 +513,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: setCaseConfigResponse: $ref: '#/components/examples/set_case_configuration_response' @@ -582,22 +638,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -606,27 +666,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -634,46 +704,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: updateCaseConfigurationResponse: $ref: '#/components/examples/update_case_configuration_response' @@ -709,20 +793,27 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic examples: getReportersResponse: $ref: '#/components/examples/get_reporters_response' @@ -1028,8 +1119,9 @@ paths: content: application/json: schema: - type: object - nullable: true + type: + - object + - 'null' responses: '200': description: Indicates a successful call. @@ -1344,7 +1436,7 @@ paths: title: type: string description: The case title. - example: + examples: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case '401': @@ -1409,22 +1501,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -1433,27 +1529,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -1461,46 +1567,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: getConfigurationResponse: $ref: '#/components/examples/get_case_configuration_response' @@ -1571,22 +1691,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -1595,27 +1719,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -1623,46 +1757,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: setCaseConfigResponse: $ref: '#/components/examples/set_case_configuration_response' @@ -1735,22 +1883,26 @@ paths: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' created_at: type: string format: date-time - example: '2022-06-01T17:07:17.767Z' + examples: + - '2022-06-01T17:07:17.767Z' created_by: type: object required: @@ -1759,27 +1911,37 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic error: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -1787,46 +1949,60 @@ paths: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: '#/components/schemas/owners' updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: '2022-06-01T19:58:48.169Z' + examples: + - '2022-06-01T19:58:48.169Z' updated_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzIwNzMsMV0= + examples: + - WzIwNzMsMV0= examples: updateCaseConfigurationResponse: $ref: '#/components/examples/update_case_configuration_response' @@ -1913,20 +2089,27 @@ paths: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic examples: getReportersResponse: $ref: '#/components/examples/get_reporters_response' @@ -2269,8 +2452,9 @@ paths: content: application/json: schema: - type: object - nullable: true + type: + - object + - 'null' responses: '200': description: Indicates a successful call. @@ -2326,7 +2510,6 @@ paths: - $ref: '#/components/parameters/case_id' - $ref: '#/components/parameters/space_id' - $ref: '#/components/parameters/page_index' - example: '1' - $ref: '#/components/parameters/page_size' - $ref: '#/components/parameters/sort_order' - $ref: '#/components/parameters/user_action_types' @@ -2365,7 +2548,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' parameters: kbn_xsrf: schema: @@ -2386,7 +2570,8 @@ components: type: string minItems: 1 maxItems: 100 - example: d4e7abb0-b462-11ec-9a8d-698504725a43 + examples: + - - d4e7abb0-b462-11ec-9a8d-698504725a43 assignees: in: query name: assignees @@ -2410,7 +2595,8 @@ components: items: type: string maxItems: 100 - example: my-category + examples: + - - my-category defaultSearchOperator: in: query name: defaultSearchOperator @@ -2418,7 +2604,8 @@ components: schema: type: string default: OR - example: OR + examples: + - OR from: in: query name: from @@ -2426,7 +2613,8 @@ components: Returns only cases that were created after a specific date. The date must be specified as a KQL data range or date match expression. schema: type: string - example: now-1d + examples: + - now-1d owner: in: query name: owner @@ -2438,7 +2626,8 @@ components: - type: array items: $ref: '#/components/schemas/owners' - example: cases + examples: + - - cases page_index: in: query name: page @@ -2447,6 +2636,8 @@ components: schema: type: integer default: 1 + examples: + - 1 page_size: in: query name: perPage @@ -2467,7 +2658,8 @@ components: items: type: string maxItems: 100 - example: elastic + examples: + - - elastic search: in: query name: search @@ -2510,7 +2702,8 @@ components: - status - severity default: createdAt - example: updatedAt + examples: + - updatedAt sort_order: in: query name: sortOrder @@ -2532,7 +2725,8 @@ components: - closed - in-progress - open - example: open + examples: + - open tags: in: query name: tags @@ -2544,7 +2738,8 @@ components: items: type: string maxItems: 100 - example: tag-1 + examples: + - - tag-1 to: in: query name: to @@ -2552,7 +2747,8 @@ components: Returns only cases that were created before a specific date. The date must be specified as a KQL data range or date match expression. schema: type: string - example: now+1d + examples: + - now+1d alert_id: in: path name: alertId @@ -2560,7 +2756,8 @@ components: required: true schema: type: string - example: 09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540 + examples: + - 09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540 configuration_id: in: path name: configurationId @@ -2568,7 +2765,8 @@ components: required: true schema: type: string - example: 3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9 + examples: + - 3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9 case_id: in: path name: caseId @@ -2576,7 +2774,8 @@ components: required: true schema: type: string - example: 9c235210-6834-11ea-a78c-6ffb38a34414 + examples: + - 9c235210-6834-11ea-a78c-6ffb38a34414 includeComments: in: query name: includeComments @@ -2593,7 +2792,8 @@ components: required: true schema: type: string - example: 71ec1870-725b-11ea-a0b2-c51ea50a58e2 + examples: + - 71ec1870-725b-11ea-a0b2-c51ea50a58e2 connector_id: in: path name: connectorId @@ -2601,7 +2801,8 @@ components: required: true schema: type: string - example: abed3a70-71bd-11ea-a0b2-c51ea50a58e2 + examples: + - abed3a70-71bd-11ea-a0b2-c51ea50a58e2 user_action_types: in: query name: types @@ -2626,7 +2827,8 @@ components: - tags - title - user - example: create_case + examples: + - - create_case space_id: in: path name: spaceId @@ -2634,13 +2836,15 @@ components: required: true schema: type: string - example: default + examples: + - default schemas: assignees: - type: array + type: + - array + - 'null' description: An array containing users that are assigned to the case. maxItems: 10 - nullable: true items: type: object required: @@ -2649,7 +2853,8 @@ components: uid: type: string description: A unique identifier for the user profile. These identifiers can be found by using the suggest user profile API. - example: u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0 + examples: + - u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0 connector_properties_none: title: Create or update case request properties for no connector required: @@ -2662,21 +2867,26 @@ components: properties: fields: description: An object containing the connector fields. To create a case without a connector, specify null. To update a case to remove the connector, specify null. - nullable: true - type: string - example: null + type: + - string + - 'null' + examples: + - null id: description: The identifier for the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. type: string - example: none + examples: + - none name: description: The name of the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. type: string - example: none + examples: + - none type: description: The type of connector. To create a case without a connector, use `.none`. To update a case to remove the connector, specify `.none`. type: string - example: .none + examples: + - .none enum: - .none connector_properties_cases_webhook: @@ -2690,9 +2900,11 @@ components: type: object properties: fields: - type: string - nullable: true - example: null + type: + - string + - 'null' + examples: + - null id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -2702,7 +2914,8 @@ components: type: description: The type of connector. type: string - example: .cases-webhook + examples: + - .cases-webhook enum: - .cases-webhook connector_properties_jira: @@ -2725,16 +2938,19 @@ components: properties: issueType: description: The type of issue. - type: string - nullable: true + type: + - string + - 'null' parent: description: The key of the parent issue, when the issue type is sub-task. - type: string - nullable: true + type: + - string + - 'null' priority: description: The priority of the issue. - type: string - nullable: true + type: + - string + - 'null' id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -2744,7 +2960,8 @@ components: type: description: The type of connector. type: string - example: .jira + examples: + - .jira enum: - .jira connector_properties_resilient: @@ -2759,8 +2976,9 @@ components: properties: fields: description: An object containing the connector fields. If you want to omit any individual field, specify null as its value. - type: object - nullable: true + type: + - object + - 'null' required: - issueTypes - severityCode @@ -2782,7 +3000,8 @@ components: type: description: The type of connector. type: string - example: .resilient + examples: + - .resilient enum: - .resilient connector_properties_servicenow: @@ -2807,24 +3026,29 @@ components: properties: category: description: The category of the incident. - type: string - nullable: true + type: + - string + - 'null' impact: description: The effect an incident had on business. - type: string - nullable: true + type: + - string + - 'null' severity: description: The severity of the incident. - type: string - nullable: true + type: + - string + - 'null' subcategory: description: The subcategory of the incident. - type: string - nullable: true + type: + - string + - 'null' urgency: description: The extent to which the incident resolution can be delayed. - type: string - nullable: true + type: + - string + - 'null' id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -2834,7 +3058,8 @@ components: type: description: The type of connector. type: string - example: .servicenow + examples: + - .servicenow enum: - .servicenow connector_properties_servicenow_sir: @@ -2861,32 +3086,39 @@ components: properties: category: description: The category of the incident. - type: string - nullable: true + type: + - string + - 'null' destIp: description: Indicates whether cases will send a comma-separated list of destination IPs. - type: boolean - nullable: true + type: + - boolean + - 'null' malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes. - type: boolean - nullable: true + type: + - boolean + - 'null' malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs. - type: boolean - nullable: true + type: + - boolean + - 'null' priority: description: The priority of the issue. - type: string - nullable: true + type: + - string + - 'null' sourceIp: description: Indicates whether cases will send a comma-separated list of source IPs. - type: boolean - nullable: true + type: + - boolean + - 'null' subcategory: description: The subcategory of the incident. - type: string - nullable: true + type: + - string + - 'null' id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -2896,7 +3128,8 @@ components: type: description: The type of connector. type: string - example: .servicenow-sir + examples: + - .servicenow-sir enum: - .servicenow-sir connector_properties_swimlane: @@ -2917,8 +3150,9 @@ components: properties: caseId: description: The case identifier for Swimlane connectors. - type: string - nullable: true + type: + - string + - 'null' id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -2928,7 +3162,8 @@ components: type: description: The type of connector. type: string - example: .swimlane + examples: + - .swimlane enum: - .swimlane owners: @@ -2939,7 +3174,8 @@ components: - cases - observability - securitySolution - example: cases + examples: + - cases settings: type: object description: An object that contains the case settings. @@ -2949,7 +3185,8 @@ components: syncAlerts: description: Turns alert syncing on or off. type: boolean - example: true + examples: + - true severity_property: type: string description: The severity of the case. @@ -3036,31 +3273,40 @@ components: description: | The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. oneOf: - - type: string + - type: + - string + - 'null' minLength: 1 maxLength: 160 - nullable: true - type: boolean case_response_closed_by_properties: title: Case response properties for closed_by - type: object - nullable: true + type: + - object + - 'null' properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name @@ -3075,11 +3321,13 @@ components: type: array items: type: string - example: a6e12ac4-7bce-457b-84f6-d7ce8deb8446 + examples: + - a6e12ac4-7bce-457b-84f6-d7ce8deb8446 created_at: type: string format: date-time - example: '2023-11-06T19:29:38.424Z' + examples: + - '2023-11-06T19:29:38.424Z' created_by: type: object required: @@ -3088,171 +3336,226 @@ components: - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic id: type: string - example: 73362370-ab1a-11ec-985f-97e55adae8b9 + examples: + - 73362370-ab1a-11ec-985f-97e55adae8b9 index: type: array items: type: string - example: .internal.alerts-security.alerts-default-000001 + examples: + - .internal.alerts-security.alerts-default-000001 owner: $ref: '#/components/schemas/owners' pushed_at: - type: string + type: + - string + - 'null' format: date-time - example: null - nullable: true + examples: + - null pushed_by: - type: object + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic rule: type: object properties: id: description: The rule identifier. type: string - example: 94d80550-aaf4-11ec-985f-97e55adae8b9 + examples: + - 94d80550-aaf4-11ec-985f-97e55adae8b9 name: description: The rule name. type: string - example: security_rule + examples: + - security_rule type: type: string - example: alert + examples: + - alert enum: - alert updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true updated_by: - type: object - nullable: true + type: + - object + - 'null' required: - email - full_name - username properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic version: type: string - example: WzMwNDgsMV0= + examples: + - WzMwNDgsMV0= case_response_created_by_properties: title: Case response properties for created_by type: object properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name - username case_response_pushed_by_properties: title: Case response properties for pushed_by - type: object - nullable: true + type: + - object + - 'null' properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name - username case_response_updated_by_properties: title: Case response properties for updated_by - type: object - nullable: true + type: + - object + - 'null' properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name @@ -3265,43 +3568,53 @@ components: properties: comment: type: string - example: A new comment. + examples: + - A new comment. created_at: type: string format: date-time - example: '2022-05-13T09:16:17.416Z' + examples: + - '2022-05-13T09:16:17.416Z' created_by: $ref: '#/components/schemas/case_response_created_by_properties' id: type: string - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 owner: $ref: '#/components/schemas/owners' pushed_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: null + examples: + - null pushed_by: $ref: '#/components/schemas/case_response_pushed_by_properties' type: type: string - example: user + examples: + - user enum: - user updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true - example: null + examples: + - null updated_by: $ref: '#/components/schemas/case_response_updated_by_properties' version: type: string - example: WzIwNDMxLDFd + examples: + - WzIwNDMxLDFd external_service: - type: object - nullable: true + type: + - object + - 'null' properties: connector_id: type: string @@ -3317,24 +3630,32 @@ components: type: string format: date-time pushed_by: - type: object + type: + - object + - 'null' properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 - nullable: true + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic status: type: string description: The status of the case. @@ -3371,13 +3692,15 @@ components: assignees: $ref: '#/components/schemas/assignees' category: - type: string + type: + - string + - 'null' description: The case category. - nullable: true closed_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true closed_by: $ref: '#/components/schemas/case_response_closed_by_properties' comments: @@ -3406,7 +3729,8 @@ components: created_at: type: string format: date-time - example: '2022-05-13T09:16:17.416Z' + examples: + - '2022-05-13T09:16:17.416Z' created_by: $ref: '#/components/schemas/case_response_created_by_properties' customFields: @@ -3431,25 +3755,30 @@ components: description: | The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. oneOf: - - type: string + - type: + - string + - 'null' minLength: 1 maxLength: 160 - nullable: true - type: boolean description: type: string - example: A case description. + examples: + - A case description. duration: - type: integer + type: + - integer + - 'null' description: | The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero. - nullable: true - example: 120 + examples: + - 120 external_service: $ref: '#/components/schemas/external_service' id: type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 + examples: + - 66b9aa00-94fa-11ea-9f74-e7e108796192 owner: $ref: '#/components/schemas/owners' settings: @@ -3462,38 +3791,45 @@ components: type: array items: type: string - example: - - tag-1 + examples: + - - tag-1 title: type: string - example: Case title 1 + examples: + - Case title 1 totalAlerts: type: integer - example: 0 + examples: + - 0 totalComment: type: integer - example: 0 + examples: + - 0 updated_at: - type: string + type: + - string + - 'null' format: date-time - nullable: true updated_by: $ref: '#/components/schemas/case_response_updated_by_properties' version: type: string - example: WzUzMiwxXQ== + examples: + - WzUzMiwxXQ== 4xx_response: type: object title: Unsuccessful cases API response properties: error: type: string - example: Unauthorized + examples: + - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 update_case_request: title: Update case request description: The update case API request body varies depending on the type of connector. @@ -3556,10 +3892,11 @@ components: description: | The custom field value. If the custom field is required, it cannot be explicitly set to null. However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. oneOf: - - type: string + - type: + - string + - 'null' minLength: 1 maxLength: 160 - nullable: true - type: boolean description: description: An updated description for the case. @@ -3600,7 +3937,8 @@ components: enum: - close-by-pushing - close-by-user - example: close-by-user + examples: + - close-by-user connector_types: type: string description: The type of connector. @@ -3612,7 +3950,8 @@ components: - .servicenow - .servicenow-sir - .swimlane - example: .none + examples: + - .none set_case_configuration_request: title: Set case configuration request description: External connection details, such as the closure type and default connector for cases. @@ -3630,16 +3969,19 @@ components: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' required: @@ -3699,16 +4041,19 @@ components: properties: fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - object + - 'null' id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' required: @@ -3753,7 +4098,8 @@ components: description: | The version of the connector. To retrieve the version value, use the get configuration API. type: string - example: WzIwMiwxXQ== + examples: + - WzIwMiwxXQ== alert_response_properties: type: object properties: @@ -3777,7 +4123,8 @@ components: type: string maxItems: 1000 x-technical-preview: true - example: 6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42 + examples: + - 6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42 alert_indices: title: Alert indices description: | @@ -3799,11 +4146,13 @@ components: id: description: The rule identifier. type: string - example: 94d80550-aaf4-11ec-985f-97e55adae8b9 + examples: + - 94d80550-aaf4-11ec-985f-97e55adae8b9 name: description: The rule name. type: string - example: security_rule + examples: + - security_rule add_alert_comment_request_properties: title: Add case comment request properties for alerts required: @@ -3826,7 +4175,8 @@ components: type: description: The type of comment. type: string - example: alert + examples: + - alert enum: - alert add_user_comment_request_properties: @@ -3838,13 +4188,15 @@ components: description: The new comment. It is required only when `type` is `user`. type: string maxLength: 30000 - example: A new comment. + examples: + - A new comment. owner: $ref: '#/components/schemas/owners' type: type: string description: The type of comment. - example: user + examples: + - user enum: - user required: @@ -3878,7 +4230,8 @@ components: type: string description: | The identifier for the comment. To retrieve comment IDs, use the get comments API. - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 index: $ref: '#/components/schemas/alert_indices' owner: @@ -3890,12 +4243,14 @@ components: type: string enum: - alert - example: alert + examples: + - alert version: description: | The current comment version. To retrieve version values, use the get comments API. type: string - example: Wzk1LDFd + examples: + - Wzk1LDFd update_user_comment_request_properties: title: Update case comment request properties for user comments description: Defines properties for case comment requests when type is user. @@ -3905,12 +4260,14 @@ components: description: The new comment. It is required only when `type` is `user`. type: string maxLength: 30000 - example: A new comment. + examples: + - A new comment. id: type: string description: | The identifier for the comment. To retrieve comment IDs, use the get comments API. - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 owner: $ref: '#/components/schemas/owners' type: @@ -3918,12 +4275,14 @@ components: description: The type of comment. enum: - user - example: user + examples: + - user version: description: | The current comment version. To retrieve version values, use the get comments API. type: string - example: Wzk1LDFd + examples: + - Wzk1LDFd required: - comment - id @@ -3946,7 +4305,8 @@ components: - delete - push_to_service - update - example: create + examples: + - create payload_alert_comment: type: object properties: @@ -3956,14 +4316,16 @@ components: alertId: oneOf: - type: string - example: 1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d + examples: + - 1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d - type: array items: type: string index: oneOf: - type: string - example: .alerts-observability.logs.alerts-default + examples: + - .alerts-observability.logs.alerts-default - type: array items: type: string @@ -3975,11 +4337,13 @@ components: id: description: The rule identifier. type: string - example: 94d80550-aaf4-11ec-985f-97e55adae8b9 + examples: + - 94d80550-aaf4-11ec-985f-97e55adae8b9 name: description: The rule name. type: string - example: security_rule + examples: + - security_rule type: type: string enum: @@ -3996,9 +4360,11 @@ components: type: object properties: fields: - description: An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. - nullable: true - type: object + description: | + An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. + type: + - object + - 'null' properties: caseId: description: The case identifier for Swimlane connectors. @@ -4008,8 +4374,9 @@ components: type: string destIp: description: Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' impact: description: The effect an incident had on business for ServiceNow ITSM connectors. type: string @@ -4023,12 +4390,14 @@ components: type: string malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' parent: description: The key of the parent issue, when the issue type is sub-task for Jira connectors. type: string @@ -4043,23 +4412,27 @@ components: type: string sourceIp: description: Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' subcategory: description: The subcategory of the incident for ServiceNow ITSM connectors. type: string urgency: description: The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. type: string - example: null + examples: + - null id: description: The identifier for the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none name: description: The name of the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' payload_create_case: @@ -4071,9 +4444,11 @@ components: type: object properties: fields: - description: An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. - nullable: true - type: object + description: | + An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. + type: + - object + - 'null' properties: caseId: description: The case identifier for Swimlane connectors. @@ -4083,8 +4458,9 @@ components: type: string destIp: description: Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' impact: description: The effect an incident had on business for ServiceNow ITSM connectors. type: string @@ -4098,12 +4474,14 @@ components: type: string malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' parent: description: The key of the parent issue, when the issue type is sub-task for Jira connectors. type: string @@ -4118,23 +4496,27 @@ components: type: string sourceIp: description: Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - boolean + - 'null' subcategory: description: The subcategory of the incident for ServiceNow ITSM connectors. type: string urgency: description: The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. type: string - example: null + examples: + - null id: description: The identifier for the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none name: description: The name of the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none type: $ref: '#/components/schemas/connector_types' description: @@ -4151,14 +4533,15 @@ components: type: array items: type: string - example: - - tag-1 + examples: + - - tag-1 title: type: string payload_delete: - type: object + type: + - object + - 'null' description: If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable. - nullable: true payload_description: type: object properties: @@ -4191,8 +4574,8 @@ components: type: array items: type: string - example: - - tag-1 + examples: + - - tag-1 payload_title: type: object properties: @@ -4228,7 +4611,8 @@ components: - status - settings - severity - example: create_case + examples: + - create_case user_actions_response_properties: type: object required: @@ -4246,36 +4630,48 @@ components: $ref: '#/components/schemas/actions' action_id: type: string - example: 22fd3e30-03b1-11ed-920c-974bfa104448 + examples: + - 22fd3e30-03b1-11ed-920c-974bfa104448 case_id: type: string - example: 22df07d0-03b1-11ed-920c-974bfa104448 + examples: + - 22df07d0-03b1-11ed-920c-974bfa104448 comment_id: - type: string - nullable: true - example: 578608d0-03b1-11ed-920c-974bfa104448 + type: + - string + - 'null' + examples: + - 578608d0-03b1-11ed-920c-974bfa104448 created_at: type: string format: date-time - example: '2022-05-13T09:16:17.416Z' + examples: + - '2022-05-13T09:16:17.416Z' created_by: type: object properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name @@ -4315,38 +4711,49 @@ components: action: $ref: '#/components/schemas/actions' comment_id: - type: string - nullable: true - example: 578608d0-03b1-11ed-920c-974bfa104448 + type: + - string + - 'null' + examples: + - 578608d0-03b1-11ed-920c-974bfa104448 created_at: type: string format: date-time - example: '2022-05-13T09:16:17.416Z' + examples: + - '2022-05-13T09:16:17.416Z' created_by: type: object properties: email: - type: string - example: null - nullable: true + type: + - string + - 'null' + examples: + - null full_name: - type: string - example: null - nullable: true - username: - type: string - example: elastic - nullable: true + type: + - string + - 'null' + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + username: + type: + - string + - 'null' + examples: + - elastic required: - email - full_name - username id: type: string - example: 22fd3e30-03b1-11ed-920c-974bfa104448 + examples: + - 22fd3e30-03b1-11ed-920c-974bfa104448 owner: $ref: '#/components/schemas/owners' payload: @@ -4366,7 +4773,8 @@ components: - $ref: '#/components/schemas/payload_user_comment' version: type: string - example: WzM1ODg4LDFd + examples: + - WzM1ODg4LDFd type: type: string description: The type of action. @@ -4382,7 +4790,8 @@ components: - status - settings - severity - example: create_case + examples: + - create_case examples: create_case_request: summary: Create a security case that uses a Jira connector. diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/alert_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/alert_id.yaml index 8677b327b91b..24c728f017d1 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/alert_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/alert_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the alert. required: true schema: type: string - example: 09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540 \ No newline at end of file + examples: + - 09f0c261e39e36351d75995b78bb83673774d1bc2cca9df2d15f0e5c0a99a540 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/case_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/case_id.yaml index eebde8582374..de7cfebbeb6b 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/case_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/case_id.yaml @@ -4,4 +4,5 @@ description: The identifier for the case. To retrieve case IDs, use the find cas required: true schema: type: string - example: 9c235210-6834-11ea-a78c-6ffb38a34414 \ No newline at end of file + examples: + - 9c235210-6834-11ea-a78c-6ffb38a34414 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/category.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/category.yaml index 8bf20d9aa245..8d28898750ae 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/category.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/category.yaml @@ -8,4 +8,5 @@ schema: items: type: string maxItems: 100 -example: my-category \ No newline at end of file + examples: + - [ my-category ] \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/comment_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/comment_id.yaml index a46f47569e8d..852ad328c6c4 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/comment_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/comment_id.yaml @@ -6,4 +6,5 @@ description: > required: true schema: type: string - example: '71ec1870-725b-11ea-a0b2-c51ea50a58e2' \ No newline at end of file + examples: + - '71ec1870-725b-11ea-a0b2-c51ea50a58e2' \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/configuration_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/configuration_id.yaml index 65cce12afaa9..884821a79952 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/configuration_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/configuration_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the configuration. required: true schema: type: string - example: 3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9 \ No newline at end of file + examples: + - 3297a0f0-b5ec-11ec-b141-0fdb20a7f9a9 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/connector_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/connector_id.yaml index 71cdc7191cfa..7fc146b22126 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/connector_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/connector_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the connector. To retrieve connector IDs, use the required: true schema: type: string - example: abed3a70-71bd-11ea-a0b2-c51ea50a58e2 \ No newline at end of file + examples: + - abed3a70-71bd-11ea-a0b2-c51ea50a58e2 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/defaultSearchOperator.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/defaultSearchOperator.yaml index 8e9004c859b4..cd3cf8cb1c00 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/defaultSearchOperator.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/defaultSearchOperator.yaml @@ -4,4 +4,5 @@ description: he default operator to use for the simple_query_string. schema: type: string default: OR -example: OR \ No newline at end of file + examples: + - OR \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/from.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/from.yaml index 6f9a24dae595..bf92b68ad6ba 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/from.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/from.yaml @@ -5,4 +5,5 @@ description: > The date must be specified as a KQL data range or date match expression. schema: type: string - example: now-1d \ No newline at end of file + examples: + - now-1d \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/ids.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/ids.yaml index c84ec64ab2a5..acd48cd0955a 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/ids.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/ids.yaml @@ -10,4 +10,5 @@ schema: type: string minItems: 1 maxItems: 100 -example: d4e7abb0-b462-11ec-9a8d-698504725a43 + examples: + - [ d4e7abb0-b462-11ec-9a8d-698504725a43 ] diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/owner.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/owner.yaml index 3c5e511742bf..d4f40a440372 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/owner.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/owner.yaml @@ -10,4 +10,5 @@ schema: - type: array items: $ref: '../schemas/owners.yaml' -example: cases \ No newline at end of file + examples: + - [ cases ] \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/page_index.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/page_index.yaml index 9176d3b62094..8ac69a105d15 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/page_index.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/page_index.yaml @@ -5,3 +5,5 @@ required: false schema: type: integer default: 1 + examples: + - 1 diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/reporters.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/reporters.yaml index db28a6c48ae0..3d4d24cafd3c 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/reporters.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/reporters.yaml @@ -8,4 +8,5 @@ schema: items: type: string maxItems: 100 -example: elastic + examples: + - [ elastic ] diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/sortField.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/sortField.yaml index 9df834cf9f5a..d5a49214e9d9 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/sortField.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/sortField.yaml @@ -12,4 +12,5 @@ schema: - status - severity default: createdAt -example: updatedAt \ No newline at end of file + examples: + - updatedAt \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml index 0a9fba457e3e..45787e844cae 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/space_id.yaml @@ -4,4 +4,5 @@ description: An identifier for the space. If `/s/` and the identifier are omitte required: true schema: type: string - example: default + examples: + - default diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/status.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/status.yaml index 0517e7516a87..b90edcd58286 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/status.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/status.yaml @@ -7,4 +7,5 @@ schema: - closed - in-progress - open -example: open \ No newline at end of file + examples: + - open \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/tags.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/tags.yaml index d899edbcc38e..b1732fb12457 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/tags.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/tags.yaml @@ -8,4 +8,5 @@ schema: items: type: string maxItems: 100 -example: tag-1 + examples: + - [ tag-1 ] diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/to.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/to.yaml index c176ce840780..dd326cabd8dc 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/to.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/to.yaml @@ -5,4 +5,5 @@ description: > The date must be specified as a KQL data range or date match expression. schema: type: string -example: now+1d \ No newline at end of file + examples: + - now+1d \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/parameters/user_action_types.yaml b/x-pack/plugins/cases/docs/openapi/components/parameters/user_action_types.yaml index 2b04b7c80662..320dc67b631c 100644 --- a/x-pack/plugins/cases/docs/openapi/components/parameters/user_action_types.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/parameters/user_action_types.yaml @@ -21,4 +21,5 @@ schema: - tags - title - user -example: create_case \ No newline at end of file + examples: + - [ create_case ] \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml index 75d0ac39903b..72d3bd82cbf6 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/4xx_response.yaml @@ -3,9 +3,11 @@ title: Unsuccessful cases API response properties: error: type: string - example: Unauthorized + examples: + - Unauthorized message: type: string statusCode: type: integer - example: 401 \ No newline at end of file + examples: + - 401 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/action_types.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/action_types.yaml index 3568008b0700..140b606b4456 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/action_types.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/action_types.yaml @@ -13,4 +13,5 @@ enum: - status - settings - severity -example: create_case \ No newline at end of file +examples: + - create_case \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/actions.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/actions.yaml index 1638ed67c78e..f2b20517efd5 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/actions.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/actions.yaml @@ -5,4 +5,5 @@ enum: - delete - push_to_service - update -example: create \ No newline at end of file +examples: + - create \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/add_alert_comment_request_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/add_alert_comment_request_properties.yaml index c99ebb19cc81..192e12f62857 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/add_alert_comment_request_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/add_alert_comment_request_properties.yaml @@ -19,6 +19,7 @@ properties: type: description: The type of comment. type: string - example: alert + examples: + - alert enum: - alert \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/add_user_comment_request_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/add_user_comment_request_properties.yaml index beac63c377ad..a0740dbdc51b 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/add_user_comment_request_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/add_user_comment_request_properties.yaml @@ -6,13 +6,15 @@ properties: description: The new comment. It is required only when `type` is `user`. type: string maxLength: 30000 - example: A new comment. + examples: + - A new comment. owner: $ref: 'owners.yaml' type: type: string description: The type of comment. - example: user + examples: + - user enum: - user required: diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/alert_comment_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/alert_comment_response_properties.yaml index 443d9dcc5552..3305732cee6e 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/alert_comment_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/alert_comment_response_properties.yaml @@ -7,11 +7,13 @@ properties: type: array items: type: string - example: a6e12ac4-7bce-457b-84f6-d7ce8deb8446 + examples: + - a6e12ac4-7bce-457b-84f6-d7ce8deb8446 created_at: type: string format: date-time - example: 2023-11-06T19:29:38.424Z + examples: + - 2023-11-06T19:29:38.424Z created_by: type: object required: @@ -22,44 +24,52 @@ properties: $ref: 'user_properties.yaml' id: type: string - example: 73362370-ab1a-11ec-985f-97e55adae8b9 + examples: + - 73362370-ab1a-11ec-985f-97e55adae8b9 index: type: array items: type: string - example: .internal.alerts-security.alerts-default-000001 + examples: + - .internal.alerts-security.alerts-default-000001 owner: $ref: 'owners.yaml' pushed_at: - type: string + type: + - "string" + - "null" format: date-time - example: null - nullable: true + examples: + - null pushed_by: - type: object + type: + - "object" + - "null" required: - email - full_name - username properties: $ref: 'user_properties.yaml' - nullable: true rule: type: object properties: $ref: 'rule_properties.yaml' type: type: string - example: alert + examples: + - alert enum: - alert updated_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true updated_by: - type: object - nullable: true + type: + - "object" + - "null" required: - email - full_name @@ -68,4 +78,5 @@ properties: $ref: 'user_properties.yaml' version: type: string - example: WzMwNDgsMV0= \ No newline at end of file + examples: + - WzMwNDgsMV0= \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/alert_identifiers.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/alert_identifiers.yaml index cca8eb74f501..5a8f821931f5 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/alert_identifiers.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/alert_identifiers.yaml @@ -13,4 +13,5 @@ oneOf: type: string maxItems: 1000 x-technical-preview: true -example: 6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42 \ No newline at end of file +examples: + - 6b24c4dc44bc720cfc92797f3d61fff952f2b2627db1fb4f8cc49f4530c4ff42 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/assignees.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/assignees.yaml index 5b4e18517bd4..4109c4d47690 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/assignees.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/assignees.yaml @@ -1,7 +1,8 @@ -type: array +type: + - "array" + - "null" description: An array containing users that are assigned to the case. maxItems: 10 -nullable: true items: type: object required: @@ -10,4 +11,5 @@ items: uid: type: string description: A unique identifier for the user profile. These identifiers can be found by using the suggest user profile API. - example: u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0 \ No newline at end of file + examples: + - u_0wpfV1MqYDaXzLtRVY-gLMrddKDEmfz51Fszhj7hWC8_0 \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_connector_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_connector_properties.yaml index ce1669c37941..3873a8ae9e0f 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_connector_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_connector_properties.yaml @@ -1,14 +1,17 @@ fields: description: The fields specified in the case configuration are not used and are not propagated to individual cases, therefore it is recommended to set it to `null`. - nullable: true - type: object + type: + - "object" + - "null" id: description: The identifier for the connector. If you do not want a default connector, use `none`. To retrieve connector IDs, use the find connectors API. type: string - example: none + examples: + - none name: description: The name of the connector. If you do not want a default connector, use `none`. To retrieve connector names, use the find connectors API. type: string - example: none + examples: + - none type: $ref: 'connector_types.yaml' \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_response_properties.yaml index 62bddb7a2597..e85179f3053a 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_configure_response_properties.yaml @@ -15,7 +15,8 @@ connector: created_at: type: string format: date-time - example: 2022-06-01T17:07:17.767Z + examples: + - 2022-06-01T17:07:17.767Z created_by: type: object required: @@ -25,12 +26,15 @@ created_by: properties: $ref: 'user_properties.yaml' error: - type: string - nullable: true - example: null + type: + - "string" + - "null" + examples: + - null id: type: string - example: 4a97a440-e1cd-11ec-be9b-9b1838238ee6 + examples: + - 4a97a440-e1cd-11ec-be9b-9b1838238ee6 mappings: type: array items: @@ -38,29 +42,36 @@ mappings: properties: action_type: type: string - example: overwrite + examples: + - overwrite source: type: string - example: title + examples: + - title target: type: string - example: summary + examples: + - summary owner: $ref: 'owners.yaml' updated_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true - example: 2022-06-01T19:58:48.169Z + examples: + - 2022-06-01T19:58:48.169Z updated_by: - type: object + type: + - "object" + - "null" required: - email - full_name - username properties: $ref: 'user_properties.yaml' - nullable: true version: type: string - example: WzIwNzMsMV0= \ No newline at end of file + examples: + - WzIwNzMsMV0= \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_customfields.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_customfields.yaml index 4170833e818c..5a4c9f26e09b 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_customfields.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_customfields.yaml @@ -18,8 +18,9 @@ value: However, for cases that existed when the required custom field was added, the default value stored in Elasticsearch is `undefined`. The value returned in the API and user interface in this case is `null`. oneOf: - - type: string + - type: + - "string" + - "null" minLength: 1 maxLength: 160 - nullable: true - type: boolean diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_closed_by_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_closed_by_properties.yaml index 95bd14e4957a..26b3eaa7395e 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_closed_by_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_closed_by_properties.yaml @@ -1,6 +1,7 @@ title: Case response properties for closed_by -type: object -nullable: true +type: + - "object" + - "null" properties: $ref: 'user_properties.yaml' required: diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_connector_field_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_connector_field_properties.yaml index 1ac30d325d45..18f79997e31c 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_connector_field_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_connector_field_properties.yaml @@ -1,7 +1,8 @@ title: Case response properties for connector fields -type: object +type: + - "object" + - "null" description: An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. -nullable: true properties: caseId: description: The case identifier for Swimlane connectors. @@ -11,8 +12,9 @@ properties: type: string destIp: description: Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" impact: description: The effect an incident had on business for ServiceNow ITSM connectors. type: string @@ -26,12 +28,14 @@ properties: type: string malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" parent: description: The key of the parent issue, when the issue type is sub-task for Jira connectors. type: string diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_properties.yaml index 60c6520d2f4c..8f3de83d88c6 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_properties.yaml @@ -26,13 +26,15 @@ properties: assignees: $ref: 'assignees.yaml' category: - type: string + type: + - "string" + - "null" description: The case category. - nullable: true closed_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true closed_by: $ref: 'case_response_closed_by_properties.yaml' comments: @@ -61,7 +63,8 @@ properties: created_at: type: string format: date-time - example: '2022-05-13T09:16:17.416Z' + examples: + - '2022-05-13T09:16:17.416Z' created_by: $ref: 'case_response_created_by_properties.yaml' customFields: @@ -74,21 +77,25 @@ properties: $ref: 'case_customfields.yaml' description: type: string - example: A case description. + examples: + - A case description. duration: - type: integer + type: + - "integer" + - "null" description: > The elapsed time from the creation of the case to its closure (in seconds). If the case has not been closed, the duration is set to null. If the case was closed after less than half a second, the duration is rounded down to zero. - nullable: true - example: 120 + examples: + - 120 external_service: $ref: 'external_service.yaml' id: type: string - example: 66b9aa00-94fa-11ea-9f74-e7e108796192 + examples: + - 66b9aa00-94fa-11ea-9f74-e7e108796192 owner: $ref: 'owners.yaml' settings: @@ -101,23 +108,28 @@ properties: type: array items: type: string - example: - - tag-1 + examples: + - [tag-1] title: type: string - example: Case title 1 + examples: + - Case title 1 totalAlerts: type: integer - example: 0 + examples: + - 0 totalComment: type: integer - example: 0 + examples: + - 0 updated_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true updated_by: $ref: 'case_response_updated_by_properties.yaml' version: type: string - example: WzUzMiwxXQ== + examples: + - WzUzMiwxXQ== diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_pushed_by_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_pushed_by_properties.yaml index c59a5565c98b..72f2c3ef619a 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_pushed_by_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_pushed_by_properties.yaml @@ -1,6 +1,7 @@ title: Case response properties for pushed_by -type: object -nullable: true +type: + - "object" + - "null" properties: $ref: 'user_properties.yaml' required: diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_updated_by_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_updated_by_properties.yaml index cd1bae033f2f..8e475c5d205d 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_updated_by_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/case_response_updated_by_properties.yaml @@ -1,6 +1,7 @@ title: Case response properties for updated_by -type: object -nullable: true +type: + - "object" + - "null" properties: $ref: 'user_properties.yaml' required: diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/closure_types.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/closure_types.yaml index 6879f820d6f5..8484d4d051ca 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/closure_types.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/closure_types.yaml @@ -3,4 +3,5 @@ description: Indicates whether a case is automatically closed when it is pushed enum: - close-by-pushing - close-by-user -example: close-by-user \ No newline at end of file +examples: + - close-by-user \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/comment_types.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/comment_types.yaml index 9731b8ce4fad..6a41e07aada4 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/comment_types.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/comment_types.yaml @@ -3,4 +3,5 @@ description: The type of comment. enum: - alert - user -example: user \ No newline at end of file +examples: + - user \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties.yaml index 9416a31f3877..e68c226ee9b9 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties.yaml @@ -1,7 +1,11 @@ fields: - description: An object containing the connector fields. To create a case without a connector, specify null. If you want to omit any individual field, specify null as its value. - nullable: true - type: object + description: > + An object containing the connector fields. + To create a case without a connector, specify null. + If you want to omit any individual field, specify null as its value. + type: + - "object" + - "null" properties: caseId: description: The case identifier for Swimlane connectors. @@ -11,8 +15,9 @@ fields: type: string destIp: description: Indicates whether cases will send a comma-separated list of destination IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" impact: description: The effect an incident had on business for ServiceNow ITSM connectors. type: string @@ -26,12 +31,14 @@ fields: type: string malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" parent: description: The key of the parent issue, when the issue type is sub-task for Jira connectors. type: string @@ -46,22 +53,26 @@ fields: type: string sourceIp: description: Indicates whether cases will send a comma-separated list of source IPs for ServiceNow SecOps connectors. - type: boolean - nullable: true + type: + - "boolean" + - "null" subcategory: description: The subcategory of the incident for ServiceNow ITSM connectors. type: string urgency: description: The extent to which the incident resolution can be delayed for ServiceNow ITSM connectors. type: string - example: null + examples: + - null id: description: The identifier for the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none name: description: The name of the connector. To create a case without a connector, use `none`. type: string - example: none + examples: + - none type: $ref: 'connector_types.yaml' \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_cases_webhook.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_cases_webhook.yaml index 871b3180bc22..b204dcbdd9f4 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_cases_webhook.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_cases_webhook.yaml @@ -8,9 +8,11 @@ description: Defines properties for connectors when type is `.cases-webhook`. type: object properties: fields: - type: string - nullable: true - example: null + type: + - "string" + - "null" + examples: + - null id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -20,6 +22,7 @@ properties: type: description: The type of connector. type: string - example: .cases-webhook + examples: + - .cases-webhook enum: - .cases-webhook \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_jira.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_jira.yaml index a63f1fbd568d..6eb1c0baa8e4 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_jira.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_jira.yaml @@ -17,16 +17,19 @@ properties: properties: issueType: description: The type of issue. - type: string - nullable: true + type: + - "string" + - "null" parent: description: The key of the parent issue, when the issue type is sub-task. - type: string - nullable: true + type: + - "string" + - "null" priority: description: The priority of the issue. - type: string - nullable: true + type: + - "string" + - "null" id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -36,6 +39,7 @@ properties: type: description: The type of connector. type: string - example: .jira + examples: + - .jira enum: - .jira diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_none.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_none.yaml index c1bc49372f64..2497b1357c86 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_none.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_none.yaml @@ -9,20 +9,25 @@ type: object properties: fields: description: An object containing the connector fields. To create a case without a connector, specify null. To update a case to remove the connector, specify null. - nullable: true - type: string - example: null + type: + - "string" + - "null" + examples: + - null id: description: The identifier for the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. type: string - example: none + examples: + - none name: description: The name of the connector. To create a case without a connector, use `none`. To update a case to remove the connector, specify `none`. type: string - example: none + examples: + - none type: description: The type of connector. To create a case without a connector, use `.none`. To update a case to remove the connector, specify `.none`. type: string - example: .none + examples: + - .none enum: - .none \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_resilient.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_resilient.yaml index bf7929b3060e..df8e34057de0 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_resilient.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_resilient.yaml @@ -9,8 +9,9 @@ type: object properties: fields: description: An object containing the connector fields. If you want to omit any individual field, specify null as its value. - type: object - nullable: true + type: + - "object" + - "null" required: - issueTypes - severityCode @@ -32,6 +33,7 @@ properties: type: description: The type of connector. type: string - example: .resilient + examples: + - .resilient enum: - .resilient \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow.yaml index 5bc76ab7a9dd..7a57a9e69ccc 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow.yaml @@ -19,24 +19,29 @@ properties: properties: category: description: The category of the incident. - type: string - nullable: true + type: + - "string" + - "null" impact: description: The effect an incident had on business. - type: string - nullable: true + type: + - "string" + - "null" severity: description: The severity of the incident. - type: string - nullable: true + type: + - "string" + - "null" subcategory: description: The subcategory of the incident. - type: string - nullable: true + type: + - "string" + - "null" urgency: description: The extent to which the incident resolution can be delayed. - type: string - nullable: true + type: + - "string" + - "null" id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -46,6 +51,7 @@ properties: type: description: The type of connector. type: string - example: .servicenow + examples: + - .servicenow enum: - .servicenow \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow_sir.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow_sir.yaml index 42245f9771e3..cafff746d18f 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow_sir.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_servicenow_sir.yaml @@ -21,32 +21,39 @@ properties: properties: category: description: The category of the incident. - type: string - nullable: true + type: + - "string" + - "null" destIp: description: Indicates whether cases will send a comma-separated list of destination IPs. - type: boolean - nullable: true + type: + - "boolean" + - "null" malwareHash: description: Indicates whether cases will send a comma-separated list of malware hashes. - type: boolean - nullable: true + type: + - "boolean" + - "null" malwareUrl: description: Indicates whether cases will send a comma-separated list of malware URLs. - type: boolean - nullable: true + type: + - "boolean" + - "null" priority: description: The priority of the issue. - type: string - nullable: true + type: + - "string" + - "null" sourceIp: description: Indicates whether cases will send a comma-separated list of source IPs. - type: boolean - nullable: true + type: + - "boolean" + - "null" subcategory: description: The subcategory of the incident. - type: string - nullable: true + type: + - "string" + - "null" id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -56,6 +63,7 @@ properties: type: description: The type of connector. type: string - example: .servicenow-sir + examples: + - .servicenow-sir enum: - .servicenow-sir \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_swimlane.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_swimlane.yaml index f4c138463078..9cde6dd09d7c 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_swimlane.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_properties_swimlane.yaml @@ -15,8 +15,9 @@ properties: properties: caseId: description: The case identifier for Swimlane connectors. - type: string - nullable: true + type: + - "string" + - "null" id: description: The identifier for the connector. To retrieve connector IDs, use the find connectors API. type: string @@ -26,6 +27,7 @@ properties: type: description: The type of connector. type: string - example: .swimlane + examples: + - .swimlane enum: - .swimlane \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_types.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_types.yaml index fc23b9cab5f8..4bc12b3ae948 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/connector_types.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/connector_types.yaml @@ -8,4 +8,5 @@ enum: - .servicenow - .servicenow-sir - .swimlane -example: .none \ No newline at end of file +examples: + - .none \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/external_service.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/external_service.yaml index b3b3182b8c96..411f977928a8 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/external_service.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/external_service.yaml @@ -1,5 +1,6 @@ -type: object -nullable: true +type: + - "object" + - "null" properties: connector_id: type: string @@ -15,7 +16,8 @@ properties: type: string format: date-time pushed_by: - type: object + type: + - "object" + - "null" properties: - $ref: 'user_properties.yaml' - nullable: true \ No newline at end of file + $ref: 'user_properties.yaml' \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/owners.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/owners.yaml index 9036fd5a3833..fa265756d950 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/owners.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/owners.yaml @@ -6,4 +6,5 @@ enum: - cases - observability - securitySolution -example: cases \ No newline at end of file +examples: + - cases \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_alert_comment.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_alert_comment.yaml index 0b0d3fc3c07c..eaaaa539a33c 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_alert_comment.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_alert_comment.yaml @@ -6,14 +6,16 @@ properties: alertId: oneOf: - type: string - example: 1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d + examples: + - 1c0b056b-cc9f-4b61-b5c9-cb801abd5e1d - type: array items: type: string index: oneOf: - type: string - example: .alerts-observability.logs.alerts-default + examples: + - .alerts-observability.logs.alerts-default - type: array items: type: string diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_create_case.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_create_case.yaml index 4c3043a25c7b..9bda777bccea 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_create_case.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_create_case.yaml @@ -20,6 +20,7 @@ properties: type: array items: type: string - example: ["tag-1"] + examples: + - ["tag-1"] title: type: string \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_delete.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_delete.yaml index 933d91305dca..29e16039ec27 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_delete.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_delete.yaml @@ -1,3 +1,4 @@ -type: object -description: If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable. -nullable: true \ No newline at end of file +type: + - "object" + - "null" +description: If the `action` is `delete` and the `type` is `delete_case`, the payload is nullable. \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_tags.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_tags.yaml index bed767719e6f..8ea690280251 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/payload_tags.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/payload_tags.yaml @@ -4,4 +4,5 @@ properties: type: array items: type: string - example: ["tag-1"] \ No newline at end of file + examples: + - ["tag-1"] \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/rule.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/rule.yaml index 09712b57ce13..0a4dfb828dcb 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/rule.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/rule.yaml @@ -10,8 +10,10 @@ properties: id: description: The rule identifier. type: string - example: 94d80550-aaf4-11ec-985f-97e55adae8b9 + examples: + - 94d80550-aaf4-11ec-985f-97e55adae8b9 name: description: The rule name. type: string - example: security_rule \ No newline at end of file + examples: + - security_rule \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/rule_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/rule_properties.yaml index 64b93b77429a..2ed5e0e89e8d 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/rule_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/rule_properties.yaml @@ -1,8 +1,10 @@ id: description: The rule identifier. type: string - example: 94d80550-aaf4-11ec-985f-97e55adae8b9 + examples: + - 94d80550-aaf4-11ec-985f-97e55adae8b9 name: description: The rule name. type: string - example: security_rule \ No newline at end of file + examples: + - security_rule \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/settings.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/settings.yaml index a344eb049195..576b8b9dff15 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/settings.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/settings.yaml @@ -6,4 +6,5 @@ properties: syncAlerts: description: Turns alert syncing on or off. type: boolean - example: true \ No newline at end of file + examples: + - true \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/update_alert_comment_request_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/update_alert_comment_request_properties.yaml index 2c7bd5dcc121..5c5619cec298 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/update_alert_comment_request_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/update_alert_comment_request_properties.yaml @@ -17,7 +17,8 @@ properties: description: > The identifier for the comment. To retrieve comment IDs, use the get comments API. - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 index: $ref: 'alert_indices.yaml' owner: @@ -29,10 +30,12 @@ properties: type: string enum: - alert - example: alert + examples: + - alert version: description: > The current comment version. To retrieve version values, use the get comments API. type: string - example: Wzk1LDFd \ No newline at end of file + examples: + - Wzk1LDFd \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/update_case_configuration_request.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/update_case_configuration_request.yaml index 86ba2794ea19..8a6a3aa7f302 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/update_case_configuration_request.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/update_case_configuration_request.yaml @@ -34,4 +34,5 @@ properties: The version of the connector. To retrieve the version value, use the get configuration API. type: string - example: WzIwMiwxXQ== \ No newline at end of file + examples: + - WzIwMiwxXQ== \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/update_user_comment_request_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/update_user_comment_request_properties.yaml index a83050e93eaa..003f12d63a30 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/update_user_comment_request_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/update_user_comment_request_properties.yaml @@ -6,13 +6,15 @@ properties: description: The new comment. It is required only when `type` is `user`. type: string maxLength: 30000 - example: A new comment. + examples: + - A new comment. id: type: string description: > The identifier for the comment. To retrieve comment IDs, use the get comments API. - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 owner: $ref: 'owners.yaml' type: @@ -20,13 +22,15 @@ properties: description: The type of comment. enum: - user - example: user + examples: + - user version: description: > The current comment version. To retrieve version values, use the get comments API. type: string - example: Wzk1LDFd + examples: + - Wzk1LDFd required: - comment - id diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_find_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_find_response_properties.yaml index a17f98d8007a..12b45d987598 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_find_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_find_response_properties.yaml @@ -13,13 +13,16 @@ properties: action: $ref: 'actions.yaml' comment_id: - type: string - nullable: true - example: 578608d0-03b1-11ed-920c-974bfa104448 + type: + - "string" + - "null" + examples: + - 578608d0-03b1-11ed-920c-974bfa104448 created_at: type: string format: date-time - example: 2022-05-13T09:16:17.416Z + examples: + - 2022-05-13T09:16:17.416Z created_by: type: object properties: @@ -30,7 +33,8 @@ properties: - username id: type: string - example: 22fd3e30-03b1-11ed-920c-974bfa104448 + examples: + - 22fd3e30-03b1-11ed-920c-974bfa104448 owner: $ref: 'owners.yaml' payload: @@ -50,7 +54,8 @@ properties: - $ref: 'payload_user_comment.yaml' version: type: string - example: WzM1ODg4LDFd + examples: + - WzM1ODg4LDFd type: type: string description: The type of action. @@ -66,4 +71,5 @@ properties: - status - settings - severity - example: create_case + examples: + - create_case diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_response_properties.yaml index ef39c531c357..02521d975d8d 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/user_actions_response_properties.yaml @@ -14,18 +14,23 @@ properties: $ref: 'actions.yaml' action_id: type: string - example: 22fd3e30-03b1-11ed-920c-974bfa104448 + examples: + - 22fd3e30-03b1-11ed-920c-974bfa104448 case_id: type: string - example: 22df07d0-03b1-11ed-920c-974bfa104448 + examples: + - 22df07d0-03b1-11ed-920c-974bfa104448 comment_id: - type: string - nullable: true - example: 578608d0-03b1-11ed-920c-974bfa104448 + type: + - "string" + - "null" + examples: + - 578608d0-03b1-11ed-920c-974bfa104448 created_at: type: string format: date-time - example: 2022-05-13T09:16:17.416Z + examples: + - 2022-05-13T09:16:17.416Z created_by: type: object properties: diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/user_comment_response_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/user_comment_response_properties.yaml index b1727d3279ab..832d603e366d 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/user_comment_response_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/user_comment_response_properties.yaml @@ -5,37 +5,46 @@ required: properties: comment: type: string - example: A new comment. + examples: + - A new comment. created_at: type: string format: date-time - example: 2022-05-13T09:16:17.416Z + examples: + - 2022-05-13T09:16:17.416Z created_by: $ref: 'case_response_created_by_properties.yaml' id: type: string - example: 8af6ac20-74f6-11ea-b83a-553aecdb28b6 + examples: + - 8af6ac20-74f6-11ea-b83a-553aecdb28b6 owner: $ref: 'owners.yaml' pushed_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true - example: null + examples: + - null pushed_by: $ref: 'case_response_pushed_by_properties.yaml' type: type: string - example: user + examples: + - user enum: - user updated_at: - type: string + type: + - "string" + - "null" format: date-time - nullable: true - example: null + examples: + - null updated_by: $ref: 'case_response_updated_by_properties.yaml' version: type: string - example: WzIwNDMxLDFd \ No newline at end of file + examples: + - WzIwNDMxLDFd \ No newline at end of file diff --git a/x-pack/plugins/cases/docs/openapi/components/schemas/user_properties.yaml b/x-pack/plugins/cases/docs/openapi/components/schemas/user_properties.yaml index 19b76a6000c0..3c5439ac7aee 100644 --- a/x-pack/plugins/cases/docs/openapi/components/schemas/user_properties.yaml +++ b/x-pack/plugins/cases/docs/openapi/components/schemas/user_properties.yaml @@ -1,15 +1,22 @@ email: - type: string - example: null - nullable: true + type: + - "string" + - "null" + examples: + - null full_name: - type: string - example: null - nullable: true -username: - type: string - example: elastic - nullable: true + type: + - "string" + - "null" + examples: + - null profile_uid: type: string - example: u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 + examples: + - u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0 +username: + type: + - "string" + - "null" + examples: + - elastic diff --git a/x-pack/plugins/cases/docs/openapi/entrypoint.yaml b/x-pack/plugins/cases/docs/openapi/entrypoint.yaml index 840d49eaa852..dff3dff43622 100644 --- a/x-pack/plugins/cases/docs/openapi/entrypoint.yaml +++ b/x-pack/plugins/cases/docs/openapi/entrypoint.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Cases description: OpenAPI schema for Cases endpoints - version: '0.1' + version: '0.2' contact: name: Cases Team license: @@ -90,7 +90,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml index 64ff49d17b8c..7914c8a994c6 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/api@cases@alerts@{alertid}.yaml @@ -28,7 +28,7 @@ get: title: type: string description: The case title. - example: + examples: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case '401': diff --git a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml index 321f2f6938c5..8b52cf5d013c 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/api@cases@{caseid}@connector@{connectorid}@_push.yaml @@ -14,8 +14,9 @@ post: content: application/json: schema: - type: object - nullable: true + type: + - "object" + - "null" responses: '200': description: Indicates a successful call. diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml index f1e287e05d30..0ffe229fd9e6 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@alerts@{alertid}.yaml @@ -28,7 +28,7 @@ get: title: type: string description: The case title. - example: + examples: - id: 06116b80-e1c3-11ec-be9b-9b1838238ee6 title: security_case '401': diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml index bee91522dde2..c06972c8dd0e 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@connector@{connectorid}@_push.yaml @@ -18,8 +18,9 @@ post: content: application/json: schema: - type: object - nullable: true + type: + - "object" + - "null" responses: '200': description: Indicates a successful call. diff --git a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions@_find.yaml b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions@_find.yaml index 0b5a6e660da8..9fda51fa5979 100644 --- a/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions@_find.yaml +++ b/x-pack/plugins/cases/docs/openapi/paths/s@{spaceid}@api@cases@{caseid}@user_actions@_find.yaml @@ -11,7 +11,6 @@ get: - $ref: '../components/parameters/case_id.yaml' - $ref: '../components/parameters/space_id.yaml' - $ref: '../components/parameters/page_index.yaml' - example: "1" - $ref: '../components/parameters/page_size.yaml' - $ref: '../components/parameters/sort_order.yaml' - $ref: '../components/parameters/user_action_types.yaml' diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx index d648fc2b6fae..5d9a6836f6e5 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx @@ -134,7 +134,8 @@ const useGetCaseUsersMock = useGetCaseUsers as jest.Mock; const useOnUpdateFieldMock = useOnUpdateField as jest.Mock; const useCasesFeaturesMock = useCasesFeatures as jest.Mock; -describe('Case View Page activity tab', () => { +// FLAKY: https://github.com/elastic/kibana/issues/171575 +describe.skip('Case View Page activity tab', () => { const caseConnectors = getCaseConnectorsMockResponse(); beforeAll(() => { diff --git a/x-pack/plugins/cloud/public/plugin.test.ts b/x-pack/plugins/cloud/public/plugin.test.ts index 3709dd7cfcb9..99e6f97946cc 100644 --- a/x-pack/plugins/cloud/public/plugin.test.ts +++ b/x-pack/plugins/cloud/public/plugin.test.ts @@ -197,8 +197,10 @@ describe('Cloud Plugin', () => { return { coreSetup, plugin }; }; - it('registers help support URL', async () => { - const { plugin } = startPlugin(); + it('registers help support URL: default', async () => { + const { plugin } = startPlugin({ + id: undefined, + }); const coreStart = coreMock.createStart(); plugin.start(coreStart); @@ -211,6 +213,41 @@ describe('Cloud Plugin', () => { `); }); + it('registers help support URL: serverless projects', async () => { + const { plugin } = startPlugin({ + id: 'my-awesome-project-id', + serverless: { + project_id: 'my-awesome-serverless-project-id', + }, + }); + + const coreStart = coreMock.createStart(); + plugin.start(coreStart); + + expect(coreStart.chrome.setHelpSupportUrl).toHaveBeenCalledTimes(1); + expect(coreStart.chrome.setHelpSupportUrl.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "https://support.elastic.co/?serverless_project_id=my-awesome-serverless-project-id", + ] + `); + }); + + it('registers help support URL: non-serverless projects', async () => { + const { plugin } = startPlugin({ + id: 'my-awesome-project-id', + }); + + const coreStart = coreMock.createStart(); + plugin.start(coreStart); + + expect(coreStart.chrome.setHelpSupportUrl).toHaveBeenCalledTimes(1); + expect(coreStart.chrome.setHelpSupportUrl.mock.calls[0]).toMatchInlineSnapshot(` + Array [ + "https://support.elastic.co/?cloud_deployment_id=my-awesome-project-id", + ] + `); + }); + describe('isServerlessEnabled', () => { it('is `true` when `serverless.projectId` is set', () => { const { plugin } = startPlugin({ diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index 3aaaf8f14fe2..f0e7b8f713e8 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -11,10 +11,11 @@ import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kb import { registerCloudDeploymentMetadataAnalyticsContext } from '../common/register_cloud_deployment_id_analytics_context'; import { getIsCloudEnabled } from '../common/is_cloud_enabled'; import { parseDeploymentIdFromDeploymentUrl } from '../common/parse_deployment_id_from_deployment_url'; -import { ELASTIC_SUPPORT_LINK, CLOUD_SNAPSHOTS_PATH } from '../common/constants'; +import { CLOUD_SNAPSHOTS_PATH } from '../common/constants'; import { decodeCloudId, type DecodedCloudId } from '../common/decode_cloud_id'; import type { CloudSetup, CloudStart } from './types'; import { getFullCloudUrl } from '../common/utils'; +import { getSupportUrl } from './utils'; export interface CloudConfigType { id?: string; @@ -103,7 +104,7 @@ export class CloudPlugin implements Plugin { } public start(coreStart: CoreStart): CloudStart { - coreStart.chrome.setHelpSupportUrl(ELASTIC_SUPPORT_LINK); + coreStart.chrome.setHelpSupportUrl(getSupportUrl(this.config)); // Nest all the registered context providers under the Cloud Services Provider. // This way, plugins only need to require Cloud's context provider to have all the enriched Cloud services. diff --git a/x-pack/plugins/cloud/public/utils.ts b/x-pack/plugins/cloud/public/utils.ts new file mode 100644 index 000000000000..d2381c428fe0 --- /dev/null +++ b/x-pack/plugins/cloud/public/utils.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 { ELASTIC_SUPPORT_LINK } from '../common/constants'; +import { CloudConfigType } from './plugin'; + +export function getSupportUrl(config: CloudConfigType): string { + let supportUrl = ELASTIC_SUPPORT_LINK; + if (config.serverless?.project_id) { + // serverless projects use config.id and config.serverless.project_id + supportUrl += '?serverless_project_id=' + config.serverless.project_id; + } else if (config.id) { + // non-serverless Cloud projects only use config.id + supportUrl += '?cloud_deployment_id=' + config.id; + } + return supportUrl; +} diff --git a/x-pack/plugins/cloud_security_posture/public/components/subscription_not_allowed.tsx b/x-pack/plugins/cloud_security_posture/public/components/subscription_not_allowed.tsx index 644455e5a2a6..a2d8f4fe32c0 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/subscription_not_allowed.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/subscription_not_allowed.tsx @@ -6,15 +6,8 @@ */ import React from 'react'; -import { EuiEmptyPrompt, EuiPageSection } from '@elastic/eui'; +import { EuiEmptyPrompt, EuiLink, EuiPageSection } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { SubscriptionLink } from '@kbn/subscription-tracking'; -import type { SubscriptionContextData } from '@kbn/subscription-tracking'; - -const subscriptionContext: SubscriptionContextData = { - feature: 'cloud-security-posture', - source: 'security__cloud-security-posture', -}; export const SubscriptionNotAllowed = ({ licenseManagementLocator, @@ -41,12 +34,12 @@ export const SubscriptionNotAllowed = ({ defaultMessage="To use these cloud security features, you must {link}." values={{ link: ( - + - + ), }} /> diff --git a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx index 3f89c934e5dd..bdccb0785162 100755 --- a/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx +++ b/x-pack/plugins/cloud_security_posture/public/test/test_provider.tsx @@ -11,7 +11,6 @@ import { I18nProvider } from '@kbn/i18n-react'; // eslint-disable-next-line no-restricted-imports import { Router } from 'react-router-dom'; import { Route, Routes } from '@kbn/shared-ux-router'; -import { MockSubscriptionTrackingProvider } from '@kbn/subscription-tracking/mocks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { coreMock } from '@kbn/core/public/mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; @@ -52,11 +51,9 @@ export const TestProvider: React.FC> = ({ - - - <>{children}} /> - - + + <>{children}} /> + diff --git a/x-pack/plugins/cloud_security_posture/tsconfig.json b/x-pack/plugins/cloud_security_posture/tsconfig.json index 113ddcb92202..0d70ed5c6be6 100755 --- a/x-pack/plugins/cloud_security_posture/tsconfig.json +++ b/x-pack/plugins/cloud_security_posture/tsconfig.json @@ -50,7 +50,6 @@ "@kbn/share-plugin", "@kbn/core-http-server", "@kbn/core-http-browser", - "@kbn/subscription-tracking", "@kbn/discover-utils", "@kbn/unified-data-table", "@kbn/cell-actions", diff --git a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js index e020950668a8..536c188b4836 100644 --- a/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js +++ b/x-pack/plugins/cross_cluster_replication/public/__jest__/client_integration/follower_indices_list.test.js @@ -309,8 +309,7 @@ describe('', () => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/100951 - describe.skip('detail panel', () => { + describe('detail panel', () => { test('should open a detail panel when clicking on a follower index', async () => { expect(exists('followerIndexDetail')).toBe(false); @@ -372,7 +371,8 @@ describe('', () => { ); }); - test('should have a section to render the follower index shards stats', async () => { + // FLAKY: https://github.com/elastic/kibana/issues/100951 + test.skip('should have a section to render the follower index shards stats', async () => { await actions.clickFollowerIndexAt(0); expect(exists('followerIndexDetail.shardsStatsSection')).toBe(true); diff --git a/x-pack/plugins/dataset_quality/common/constants.ts b/x-pack/plugins/dataset_quality/common/constants.ts new file mode 100644 index 000000000000..febb7d2a0f9f --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/constants.ts @@ -0,0 +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. + */ + +export const DATASET_QUALITY_APP_ID = 'dataset_quality'; +export const DATA_STREAMS_STATS_URL = '/internal/dataset_quality/data_streams/stats'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index.ts b/x-pack/plugins/dataset_quality/common/data_streams/index.ts similarity index 80% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index.ts rename to x-pack/plugins/dataset_quality/common/data_streams/index.ts index e78ffe1c9086..6cc0ccaa93a6 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index.ts +++ b/x-pack/plugins/dataset_quality/common/data_streams/index.ts @@ -5,4 +5,4 @@ * 2.0. */ -export { IndexPatternPrompt } from './index_pattern_prompt'; +export * from './types'; diff --git a/x-pack/plugins/dataset_quality/server/types/api_types.ts b/x-pack/plugins/dataset_quality/common/data_streams/types.ts similarity index 82% rename from x-pack/plugins/dataset_quality/server/types/api_types.ts rename to x-pack/plugins/dataset_quality/common/data_streams/types.ts index 077cb94aa349..1a47a0d7e5ac 100644 --- a/x-pack/plugins/dataset_quality/server/types/api_types.ts +++ b/x-pack/plugins/dataset_quality/common/data_streams/types.ts @@ -16,7 +16,3 @@ export const dataStreamTypesRt = t.partial({ t.literal('profiling'), ]), }); - -export const sortOrderRt = t.type({ - sortOrder: t.union([t.literal('asc'), t.literal('desc')]), -}); diff --git a/x-pack/plugins/dataset_quality/common/data_streams_stats/data_stream_stat.ts b/x-pack/plugins/dataset_quality/common/data_streams_stats/data_stream_stat.ts new file mode 100644 index 000000000000..5fd2a2ffc1ff --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/data_streams_stats/data_stream_stat.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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Integration } from './integration'; +import { DataStreamStatType, IntegrationType } from './types'; + +export class DataStreamStat { + name: DataStreamStatType['name']; + title: string; + size?: DataStreamStatType['size']; + sizeBytes?: DataStreamStatType['size_bytes']; + lastActivity?: DataStreamStatType['last_activity']; + integration?: IntegrationType; + + private constructor(dataStreamStat: DataStreamStat) { + this.name = dataStreamStat.name; + this.title = dataStreamStat.title ?? dataStreamStat.name; + this.size = dataStreamStat.size; + this.sizeBytes = dataStreamStat.sizeBytes; + this.lastActivity = dataStreamStat.lastActivity; + this.integration = dataStreamStat.integration; + } + + public static create(dataStreamStat: DataStreamStatType) { + const [_type, dataset, namespace] = dataStreamStat.name.split('-'); + + const dataStreamStatProps = { + name: dataStreamStat.name, + title: `${dataset}-${namespace}`, + size: dataStreamStat.size, + sizeBytes: dataStreamStat.size_bytes, + lastActivity: dataStreamStat.last_activity, + integration: dataStreamStat.integration + ? Integration.create(dataStreamStat.integration) + : undefined, + }; + + return new DataStreamStat(dataStreamStatProps); + } +} diff --git a/x-pack/plugins/dataset_quality/common/data_streams_stats/errors.ts b/x-pack/plugins/dataset_quality/common/data_streams_stats/errors.ts new file mode 100644 index 000000000000..de47f4cb8c39 --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/data_streams_stats/errors.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export class GetDataStreamsStatsError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, new.target.prototype); + this.name = 'GetDataStreamsStatsError'; + } +} diff --git a/x-pack/plugins/dataset_quality/common/data_streams_stats/index.ts b/x-pack/plugins/dataset_quality/common/data_streams_stats/index.ts new file mode 100644 index 000000000000..28c7b0a8c274 --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/data_streams_stats/index.ts @@ -0,0 +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. + */ + +export * from './types'; +export * from './errors'; diff --git a/x-pack/plugins/dataset_quality/common/data_streams_stats/integration.ts b/x-pack/plugins/dataset_quality/common/data_streams_stats/integration.ts new file mode 100644 index 000000000000..937efd407e6f --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/data_streams_stats/integration.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { IntegrationType } from './types'; + +export class Integration { + name: IntegrationType['name']; + title: IntegrationType['title']; + version: IntegrationType['version']; + icons?: IntegrationType['icons']; + + private constructor(integration: Integration) { + this.name = integration.name; + this.title = integration.title || integration.name; + this.version = integration.version || '1.0.0'; + this.icons = integration.icons; + } + + public static create(integration: IntegrationType) { + const integrationProps = { + ...integration, + title: integration.title || integration.name, + version: integration.version || '1.0.0', + }; + + return new Integration(integrationProps); + } +} diff --git a/x-pack/plugins/dataset_quality/common/data_streams_stats/types.ts b/x-pack/plugins/dataset_quality/common/data_streams_stats/types.ts new file mode 100644 index 000000000000..f9a202798fb3 --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/data_streams_stats/types.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { APIClientRequestParamsOf, APIReturnType } from '../rest/create_call_dataset_quality_api'; +import { DataStreamStat } from './data_stream_stat'; + +export type GetDataStreamsStatsParams = + APIClientRequestParamsOf<`GET /internal/dataset_quality/data_streams/stats`>['params']; +export type GetDataStreamsStatsQuery = GetDataStreamsStatsParams['query']; +export type GetDataStreamsStatsResponse = + APIReturnType<`GET /internal/dataset_quality/data_streams/stats`>; +export type DataStreamStatServiceResponse = DataStreamStat[]; +export type DataStreamStatType = GetDataStreamsStatsResponse['dataStreamsStats'][0]; +export type IntegrationType = GetDataStreamsStatsResponse['integrations'][0]; diff --git a/x-pack/plugins/dataset_quality/common/index.ts b/x-pack/plugins/dataset_quality/common/index.ts index 2022b5168504..b015815eeaac 100644 --- a/x-pack/plugins/dataset_quality/common/index.ts +++ b/x-pack/plugins/dataset_quality/common/index.ts @@ -7,3 +7,4 @@ export type { DatasetQualityConfig } from './plugin_config'; export type { FetchOptions } from './fetch_options'; +export type { APIClientRequestParamsOf, APIReturnType } from './rest'; diff --git a/x-pack/plugins/dataset_quality/public/services/rest/call_api.ts b/x-pack/plugins/dataset_quality/common/rest/call_api.ts similarity index 95% rename from x-pack/plugins/dataset_quality/public/services/rest/call_api.ts rename to x-pack/plugins/dataset_quality/common/rest/call_api.ts index 1b39bfc90573..a70e2f8d407e 100644 --- a/x-pack/plugins/dataset_quality/public/services/rest/call_api.ts +++ b/x-pack/plugins/dataset_quality/common/rest/call_api.ts @@ -6,7 +6,7 @@ */ import { CoreSetup, CoreStart } from '@kbn/core/public'; -import { FetchOptions } from '../../../common'; +import { FetchOptions } from '..'; function getFetchOptions(fetchOptions: FetchOptions) { const { body, ...rest } = fetchOptions; diff --git a/x-pack/plugins/dataset_quality/public/services/rest/create_call_dataset_quality_api.ts b/x-pack/plugins/dataset_quality/common/rest/create_call_dataset_quality_api.ts similarity index 96% rename from x-pack/plugins/dataset_quality/public/services/rest/create_call_dataset_quality_api.ts rename to x-pack/plugins/dataset_quality/common/rest/create_call_dataset_quality_api.ts index 47d04b309817..8e3929bb77e7 100644 --- a/x-pack/plugins/dataset_quality/public/services/rest/create_call_dataset_quality_api.ts +++ b/x-pack/plugins/dataset_quality/common/rest/create_call_dataset_quality_api.ts @@ -12,8 +12,8 @@ import type { RouteRepositoryClient, } from '@kbn/server-route-repository'; import { formatRequest } from '@kbn/server-route-repository'; -import { FetchOptions } from '../../../common'; -import type { APIEndpoint, DatasetQualityServerRouteRepository } from '../../../server/routes'; +import { FetchOptions } from '..'; +import type { APIEndpoint, DatasetQualityServerRouteRepository } from '../../server/routes'; import { CallApi, callApi } from './call_api'; export type DatasetQualityClientOptions = Omit< diff --git a/x-pack/plugins/dataset_quality/common/rest/index.ts b/x-pack/plugins/dataset_quality/common/rest/index.ts new file mode 100644 index 000000000000..559acfe62e50 --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/rest/index.ts @@ -0,0 +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. + */ + +export * from './call_api'; +export * from './create_call_dataset_quality_api'; diff --git a/x-pack/plugins/dataset_quality/common/translations.ts b/x-pack/plugins/dataset_quality/common/translations.ts new file mode 100644 index 000000000000..b26b7ca5c902 --- /dev/null +++ b/x-pack/plugins/dataset_quality/common/translations.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 { i18n } from '@kbn/i18n'; + +export const datasetQualityAppTitle = i18n.translate('xpack.datasetQuality.appTitle', { + defaultMessage: 'Datasets', +}); + +export const onboardingLinkTitle = i18n.translate('xpack.datasetQuality.onboardingLinkTitle', { + defaultMessage: 'Add data', +}); + +export const noDatasetsDescription = i18n.translate('xpack.datasetQuality.noDatasetsDescription', { + defaultMessage: 'Try adjusting your time or filter.', +}); + +export const noDatasetsTitle = i18n.translate('xpack.datasetQuality.noDatasetsTitle', { + defaultMessage: 'There is no data to display.', +}); + +export const loadingDatasetsText = i18n.translate('xpack.datasetQuality.loadingDatasetsText', { + defaultMessage: 'Loading data', +}); + +export const tableSummaryAllText = i18n.translate('xpack.datasetQuality.tableSummaryAllText', { + defaultMessage: 'All', +}); + +export const tableSummaryOfText = i18n.translate('xpack.datasetQuality.tableSummaryOfText', { + defaultMessage: 'of', +}); diff --git a/x-pack/plugins/dataset_quality/kibana.jsonc b/x-pack/plugins/dataset_quality/kibana.jsonc index 133537a76d83..710d7e82890c 100644 --- a/x-pack/plugins/dataset_quality/kibana.jsonc +++ b/x-pack/plugins/dataset_quality/kibana.jsonc @@ -8,7 +8,7 @@ "server": true, "browser": true, "configPath": ["xpack", "datasetQuality"], - "requiredPlugins": ["data", "kibanaReact", "kibanaUtils", "controls", "embeddable", "share"], + "requiredPlugins": ["data", "kibanaReact", "kibanaUtils", "controls", "embeddable", "share", "observabilityShared", "fleet", "fieldFormats"], "optionalPlugins": [], "requiredBundles": [], "extraPublicDirs": ["common"] diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.tsx new file mode 100644 index 000000000000..aa653a95d622 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/columns.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 React from 'react'; +import { EuiBasicTableColumn, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { PackageIcon } from '@kbn/fleet-plugin/public'; +import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '@kbn/field-types'; +import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; +import { DataStreamStat } from '../../../common/data_streams_stats/data_stream_stat'; +import loggingIcon from '../../icons/logging.svg'; + +const nameColumnName = i18n.translate('xpack.datasetQuality.nameColumnName', { + defaultMessage: 'Dataset Name', +}); + +const sizeColumnName = i18n.translate('xpack.datasetQuality.sizeColumnName', { + defaultMessage: 'Size', +}); + +const lastActivityColumnName = i18n.translate('xpack.datasetQuality.lastActivityColumnName', { + defaultMessage: 'Last Activity', +}); + +export const getDatasetQualitTableColumns = ({ + fieldFormats, +}: { + fieldFormats: FieldFormatsStart; +}): Array> => { + return [ + { + name: nameColumnName, + field: 'title', + sortable: true, + render: (title: string, dataStreamStat: DataStreamStat) => { + const { integration } = dataStreamStat; + + return ( + + + {integration ? ( + + ) : ( + + )} + + {title} + + ); + }, + }, + { + name: sizeColumnName, + field: 'size', + sortable: true, + }, + { + name: lastActivityColumnName, + field: 'lastActivity', + render: (timestamp: number) => + fieldFormats + .getDefaultInstance(KBN_FIELD_TYPES.DATE, [ES_FIELD_TYPES.DATE]) + .convert(timestamp), + sortable: true, + }, + ]; +}; diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/context.ts b/x-pack/plugins/dataset_quality/public/components/dataset_quality/context.ts new file mode 100644 index 000000000000..64029b649a58 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/context.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { createContext, useContext } from 'react'; +import { IDataStreamsStatsClient } from '../../services/data_streams_stats'; + +export interface DatasetQualityContextValue { + dataStreamsStatsServiceClient: IDataStreamsStatsClient; +} + +export const DatasetQualityContext = createContext({} as DatasetQualityContextValue); + +export function useDatasetQualityContext() { + return useContext(DatasetQualityContext); +} diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/dataset_quality.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/dataset_quality.tsx new file mode 100644 index 000000000000..9fe6ca8db3b2 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/dataset_quality.tsx @@ -0,0 +1,55 @@ +/* + * 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 { CoreStart } from '@kbn/core/public'; +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { DataStreamsStatsService } from '../../services/data_streams_stats/data_streams_stats_service'; +import { DatasetQualityContext, DatasetQualityContextValue } from './context'; +import { useKibanaContextForPluginProvider } from '../../utils'; +import { DatasetQualityStartDeps } from '../../types'; +import { Header } from './header'; +import { Table } from './table'; + +export interface CreateDatasetQualityArgs { + core: CoreStart; + plugins: DatasetQualityStartDeps; +} + +export const createDatasetQuality = ({ core, plugins }: CreateDatasetQualityArgs) => { + return () => { + const KibanaContextProviderForPlugin = useKibanaContextForPluginProvider(core, plugins); + + const dataStreamsStatsServiceClient = new DataStreamsStatsService().start({ + http: core.http, + }).client; + + const datasetQualityProviderValue: DatasetQualityContextValue = { + dataStreamsStatsServiceClient, + }; + + return ( + + + + + + ); + }; +}; + +function DatasetQuality() { + return ( + + +
    + + + + + + ); +} diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/header.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/header.tsx new file mode 100644 index 000000000000..5126a645f7b6 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/header.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiPageHeader, EuiButton } from '@elastic/eui'; +import { + ObservabilityOnboardingLocatorParams, + OBSERVABILITY_ONBOARDING_LOCATOR, +} from '@kbn/deeplinks-observability'; +import { datasetQualityAppTitle, onboardingLinkTitle } from '../../../common/translations'; +import { useKibanaContextForPlugin } from '../../utils'; + +export function Header() { + const { + services: { share }, + } = useKibanaContextForPlugin(); + + const OnboardingLink = React.memo(() => { + const locator = share.url.locators.get( + OBSERVABILITY_ONBOARDING_LOCATOR + ); + + const onboardingUrl = locator?.getRedirectUrl({}); + + return ( + + {onboardingLinkTitle} + + ); + }); + + return ( + ]} + /> + ); +} diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/index.ts b/x-pack/plugins/dataset_quality/public/components/dataset_quality/index.ts new file mode 100644 index 000000000000..1a8591d0d3c8 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './dataset_quality'; diff --git a/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx b/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx new file mode 100644 index 000000000000..f45df6717063 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/components/dataset_quality/table.tsx @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBasicTable, EuiHorizontalRule, EuiSpacer, EuiText, EuiEmptyPrompt } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { loadingDatasetsText, noDatasetsTitle } from '../../../common/translations'; +import { useDatasetQualityTable } from '../../hooks'; + +export const Table = () => { + const { sort, onTableChange, pagination, renderedItems, columns, loading, resultsCount } = + useDatasetQualityTable(); + + return ( + <> + + + + + + {noDatasetsTitle}} + hasBorder={false} + titleSize="m" + /> + ) + } + /> + + ); +}; diff --git a/x-pack/plugins/dataset_quality/public/hooks/index.ts b/x-pack/plugins/dataset_quality/public/hooks/index.ts new file mode 100644 index 000000000000..36b6f1540c82 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/hooks/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_dataset_quality_table'; diff --git a/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx b/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx new file mode 100644 index 000000000000..30bbd7f437da --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/hooks/use_dataset_quality_table.tsx @@ -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 { orderBy } from 'lodash'; +import React, { useState, useMemo, useCallback } from 'react'; +import { useFetcher } from '@kbn/observability-shared-plugin/public'; +import { tableSummaryAllText, tableSummaryOfText } from '../../common/translations'; +import { DataStreamStat } from '../../common/data_streams_stats/data_stream_stat'; +import { getDatasetQualitTableColumns } from '../components/dataset_quality/columns'; +import { useDatasetQualityContext } from '../components/dataset_quality/context'; +import { useKibanaContextForPlugin } from '../utils'; + +const DEFAULT_SORT_FIELD = 'title'; +const DEFAULT_SORT_DIRECTION = 'desc'; +type DIRECTION = 'asc' | 'desc'; +type SORT_FIELD = keyof DataStreamStat; + +const sortingOverrides: Partial<{ [key in SORT_FIELD]: SORT_FIELD }> = { + ['size']: 'sizeBytes', +}; + +export const useDatasetQualityTable = () => { + const { + services: { fieldFormats }, + } = useKibanaContextForPlugin(); + const [pageIndex, setPageIndex] = useState(0); + const [pageSize, setPageSize] = useState(10); + const [sortField, setSortField] = useState(DEFAULT_SORT_FIELD); + const [sortDirection, setSortDirection] = useState(DEFAULT_SORT_DIRECTION); + + const { dataStreamsStatsServiceClient: client } = useDatasetQualityContext(); + const { data = [], loading } = useFetcher(async () => client.getDataStreamsStats(), []); + + const columns = useMemo(() => getDatasetQualitTableColumns({ fieldFormats }), [fieldFormats]); + + const pagination = { + pageIndex, + pageSize, + totalItemCount: data.length, + hidePerPageOptions: true, + }; + + const onTableChange = useCallback( + (options: { + page: { index: number; size: number }; + sort?: { field: SORT_FIELD; direction: DIRECTION }; + }) => { + setPageIndex(options.page.index); + setPageSize(options.page.size); + setSortField(options.sort?.field || DEFAULT_SORT_FIELD); + setSortDirection(options.sort?.direction || DEFAULT_SORT_DIRECTION); + }, + [] + ); + + const sort = { + sort: { field: sortField, direction: sortDirection }, + }; + + const renderedItems = useMemo(() => { + const overridenSortingField = sortingOverrides[sortField] || sortField; + const sortedItems = orderBy(data, overridenSortingField, sortDirection); + + return sortedItems.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize); + }, [data, sortField, sortDirection, pageIndex, pageSize]); + + const resultsCount = useMemo(() => { + const startNumberItemsOnPage = pageSize * pageIndex + (renderedItems.length ? 1 : 0); + const endNumberItemsOnPage = pageSize * pageIndex + renderedItems.length; + + return pageSize === 0 ? ( + {tableSummaryAllText} + ) : ( + <> + + {startNumberItemsOnPage}-{endNumberItemsOnPage} + {' '} + {tableSummaryOfText} {data.length} + + ); + }, [data.length, pageIndex, pageSize, renderedItems.length]); + + return { sort, onTableChange, pagination, renderedItems, columns, loading, resultsCount }; +}; diff --git a/x-pack/plugins/dataset_quality/public/icons/logging.svg b/x-pack/plugins/dataset_quality/public/icons/logging.svg new file mode 100644 index 000000000000..41d5251b3ea1 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/icons/logging.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/x-pack/plugins/dataset_quality/public/index.ts b/x-pack/plugins/dataset_quality/public/index.ts index 339be1ec1de9..e57d36776edf 100644 --- a/x-pack/plugins/dataset_quality/public/index.ts +++ b/x-pack/plugins/dataset_quality/public/index.ts @@ -14,3 +14,5 @@ export type { DatasetQualityPluginSetup, DatasetQualityPluginStart } from './typ export function plugin(context: PluginInitializerContext) { return new DatasetQualityPlugin(context); } + +export { datasetQualityAppTitle } from '../common/translations'; diff --git a/x-pack/plugins/dataset_quality/public/plugin.ts b/x-pack/plugins/dataset_quality/public/plugin.tsx similarity index 60% rename from x-pack/plugins/dataset_quality/public/plugin.ts rename to x-pack/plugins/dataset_quality/public/plugin.tsx index 520c02481cd6..c2ab65542263 100644 --- a/x-pack/plugins/dataset_quality/public/plugin.ts +++ b/x-pack/plugins/dataset_quality/public/plugin.tsx @@ -6,11 +6,12 @@ */ import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; +import { createDatasetQuality } from './components/dataset_quality'; import { DatasetQualityPluginSetup, DatasetQualityPluginStart, - DatasetQualitySetupDependencies, - DatasetQualityStartDependencies, + DatasetQualitySetupDeps, + DatasetQualityStartDeps, } from './types'; export class DatasetQualityPlugin @@ -18,14 +19,16 @@ export class DatasetQualityPlugin { constructor(context: PluginInitializerContext) {} - public setup(core: CoreSetup, plugins: DatasetQualitySetupDependencies) { + public setup(core: CoreSetup, plugins: DatasetQualitySetupDeps) { return {}; } - public start( - core: CoreStart, - plugins: DatasetQualityStartDependencies - ): DatasetQualityPluginStart { - return {}; + public start(core: CoreStart, plugins: DatasetQualityStartDeps): DatasetQualityPluginStart { + const DatasetQuality = createDatasetQuality({ + core, + plugins, + }); + + return { DatasetQuality }; } } diff --git a/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts new file mode 100644 index 000000000000..83028a3c4d66 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_client.ts @@ -0,0 +1,42 @@ +/* + * 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 { find, merge } from 'lodash'; +import { HttpStart } from '@kbn/core/public'; +import { DataStreamStat } from '../../../common/data_streams_stats/data_stream_stat'; +import { DATA_STREAMS_STATS_URL } from '../../../common/constants'; +import { + GetDataStreamsStatsError, + GetDataStreamsStatsResponse, + GetDataStreamsStatsQuery, + DataStreamStatServiceResponse, +} from '../../../common/data_streams_stats'; +import { IDataStreamsStatsClient } from './types'; + +export class DataStreamsStatsClient implements IDataStreamsStatsClient { + constructor(private readonly http: HttpStart) {} + + public async getDataStreamsStats( + params: GetDataStreamsStatsQuery = { type: 'logs' } + ): Promise { + const { dataStreamsStats, integrations } = await this.http + .get(DATA_STREAMS_STATS_URL, { + query: params, + }) + .catch((error) => { + throw new GetDataStreamsStatsError(`Failed to fetch data streams stats": ${error}`); + }); + + const mergedDataStreamsStats = dataStreamsStats.map((statsItem) => { + const integration = find(integrations, { name: statsItem.integration }); + + return integration ? merge({}, statsItem, { integration }) : statsItem; + }); + + return mergedDataStreamsStats.map(DataStreamStat.create); + } +} diff --git a/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_service.ts b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_service.ts new file mode 100644 index 000000000000..c57fe3c90ebb --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/data_streams_stats_service.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DataStreamsStatsClient } from './data_streams_stats_client'; +import { + DataStreamsStatsServiceSetup, + DataStreamsStatsServiceStartDeps, + DataStreamsStatsServiceStart, +} from './types'; + +export class DataStreamsStatsService { + constructor() {} + + public setup(): DataStreamsStatsServiceSetup {} + + public start({ http }: DataStreamsStatsServiceStartDeps): DataStreamsStatsServiceStart { + const client = new DataStreamsStatsClient(http); + + return { + client, + }; + } +} diff --git a/x-pack/plugins/dataset_quality/public/services/data_streams_stats/index.ts b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/index.ts new file mode 100644 index 000000000000..8f33568e1e88 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/index.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './data_streams_stats_client'; +export * from './data_streams_stats_service'; +export * from './types'; diff --git a/x-pack/plugins/dataset_quality/public/services/data_streams_stats/types.ts b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/types.ts new file mode 100644 index 000000000000..7023dbe25478 --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/services/data_streams_stats/types.ts @@ -0,0 +1,26 @@ +/* + * 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 { HttpStart } from '@kbn/core/public'; +import { + DataStreamStatServiceResponse, + GetDataStreamsStatsQuery, +} from '../../../common/data_streams_stats'; + +export type DataStreamsStatsServiceSetup = void; + +export interface DataStreamsStatsServiceStart { + client: IDataStreamsStatsClient; +} + +export interface DataStreamsStatsServiceStartDeps { + http: HttpStart; +} + +export interface IDataStreamsStatsClient { + getDataStreamsStats(params?: GetDataStreamsStatsQuery): Promise; +} diff --git a/x-pack/plugins/dataset_quality/public/types.ts b/x-pack/plugins/dataset_quality/public/types.ts index 2d57bd6bb1b2..482aff3b242b 100644 --- a/x-pack/plugins/dataset_quality/public/types.ts +++ b/x-pack/plugins/dataset_quality/public/types.ts @@ -5,14 +5,22 @@ * 2.0. */ +import { ComponentType } from 'react'; +import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; +import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; + // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface DatasetQualityPluginSetup {} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DatasetQualityPluginStart {} +export interface DatasetQualityPluginStart { + DatasetQuality: ComponentType; +} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DatasetQualityStartDependencies {} +export interface DatasetQualityStartDeps { + share: SharePluginStart; + fieldFormats: FieldFormatsStart; +} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DatasetQualitySetupDependencies {} +export interface DatasetQualitySetupDeps { + share: SharePluginSetup; +} diff --git a/x-pack/plugins/dataset_quality/public/utils/index.ts b/x-pack/plugins/dataset_quality/public/utils/index.ts new file mode 100644 index 000000000000..c7d8b7ba1dca --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/utils/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './use_kibana'; diff --git a/x-pack/plugins/dataset_quality/public/utils/use_kibana.tsx b/x-pack/plugins/dataset_quality/public/utils/use_kibana.tsx new file mode 100644 index 000000000000..cd13ced6af9b --- /dev/null +++ b/x-pack/plugins/dataset_quality/public/utils/use_kibana.tsx @@ -0,0 +1,35 @@ +/* + * 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 { CoreStart } from '@kbn/core/public'; +import { + createKibanaReactContext, + KibanaReactContextValue, + useKibana, +} from '@kbn/kibana-react-plugin/public'; +import { useMemo } from 'react'; +import { DatasetQualityStartDeps } from '../types'; + +export type PluginKibanaContextValue = CoreStart & DatasetQualityStartDeps; + +export const createKibanaContextForPlugin = (core: CoreStart, plugins: DatasetQualityStartDeps) => + createKibanaReactContext({ + ...core, + ...plugins, + }); + +export const useKibanaContextForPlugin = + useKibana as () => KibanaReactContextValue; + +export const useKibanaContextForPluginProvider = ( + core: CoreStart, + plugins: DatasetQualityStartDeps +) => { + const { Provider } = useMemo(() => createKibanaContextForPlugin(core, plugins), [core, plugins]); + + return Provider; +}; diff --git a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/get_data_streams.test.ts b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/get_data_streams.test.ts index ef1ecdbccb1d..0b45d6fa8b34 100644 --- a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/get_data_streams.test.ts +++ b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/get_data_streams.test.ts @@ -114,7 +114,6 @@ describe('getDataStreams', () => { esClient: esClientMock, type: 'logs', datasetQuery: 'nginx', - sortOrder: 'asc', uncategorisedOnly: true, }); expect(dataStreamService.getMatchingDataStreams).toHaveBeenCalledWith(expect.anything(), { @@ -129,7 +128,6 @@ describe('getDataStreams', () => { esClient: esClientMock, type: 'logs', datasetQuery: 'nginx', - sortOrder: 'asc', uncategorisedOnly: true, }); expect(results.items.length).toBe(1); @@ -140,62 +138,36 @@ describe('getDataStreams', () => { esClient: esClientMock, type: 'logs', datasetQuery: 'nginx', - sortOrder: 'asc', uncategorisedOnly: false, }); expect(results.items.length).toBe(5); }); }); - describe('Can be sorted', () => { - it('Ascending', async () => { - const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); - const results = await getDataStreams({ - esClient: esClientMock, - type: 'logs', - datasetQuery: 'nginx', - sortOrder: 'asc', - uncategorisedOnly: false, - }); - expect(results.items[0].name).toBe('logs-elastic_agent-default'); - }); - it('Descending', async () => { - const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); - const results = await getDataStreams({ - esClient: esClientMock, - type: 'logs', - datasetQuery: 'nginx', - sortOrder: 'desc', - uncategorisedOnly: false, - }); - expect(results.items[0].name).toBe('logs-test.test-default'); - }); - }); it('Formats the items correctly', async () => { const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); const results = await getDataStreams({ esClient: esClientMock, type: 'logs', - sortOrder: 'desc', uncategorisedOnly: false, }); - expect(results.items).toEqual([ - { name: 'logs-test.test-default' }, + expect(results.items.sort()).toEqual([ { - name: 'logs-elastic_agent.metricbeat-default', - integration: { name: 'elastic_agent', managed_by: 'fleet' }, + name: 'logs-elastic_agent-default', + integration: 'elastic_agent', }, { - name: 'logs-elastic_agent.fleet_server-default', - integration: { name: 'elastic_agent', managed_by: 'fleet' }, + name: 'logs-elastic_agent.filebeat-default', + integration: 'elastic_agent', }, { - name: 'logs-elastic_agent.filebeat-default', - integration: { name: 'elastic_agent', managed_by: 'fleet' }, + name: 'logs-elastic_agent.fleet_server-default', + integration: 'elastic_agent', }, { - name: 'logs-elastic_agent-default', - integration: { name: 'elastic_agent', managed_by: 'fleet' }, + name: 'logs-elastic_agent.metricbeat-default', + integration: 'elastic_agent', }, + { name: 'logs-test.test-default' }, ]); }); }); diff --git a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/index.ts b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/index.ts index 37181d8b8a73..6154e3bc11a2 100644 --- a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/index.ts +++ b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams/index.ts @@ -13,10 +13,9 @@ export async function getDataStreams(options: { esClient: ElasticsearchClient; type?: DataStreamTypes; datasetQuery?: string; - sortOrder: 'asc' | 'desc'; uncategorisedOnly: boolean; }) { - const { esClient, type, datasetQuery, uncategorisedOnly, sortOrder } = options; + const { esClient, type, datasetQuery, uncategorisedOnly } = options; const allDataStreams = await dataStreamService.getMatchingDataStreams(esClient, { type: type ?? '*', @@ -31,25 +30,10 @@ export async function getDataStreams(options: { const mappedDataStreams = filteredDataStreams.map((dataStream) => ({ name: dataStream.name, - ...(dataStream._meta - ? { - integration: { - name: dataStream._meta?.package?.name, - managed_by: dataStream._meta?.managed_by, - }, - } - : {}), + integration: dataStream._meta?.package?.name, })); - const sortedDataStreams = mappedDataStreams.sort((a, b) => { - if (sortOrder === 'desc') { - return b.name.localeCompare(a.name); - } - - return a.name.localeCompare(b.name); - }); - return { - items: sortedDataStreams, + items: mappedDataStreams, }; } diff --git a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/get_data_streams_stats.test.ts b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/get_data_streams_stats.test.ts index c078cb24d3d2..830c3b162573 100644 --- a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/get_data_streams_stats.test.ts +++ b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/get_data_streams_stats.test.ts @@ -63,52 +63,30 @@ describe('getDataStreams', () => { esClient: esClientMock, type: 'logs', datasetQuery: 'nginx', - sortOrder: 'asc', }); expect(dataStreamService.getMatchingDataStreamsStats).toHaveBeenCalledWith(expect.anything(), { type: 'logs', dataset: '*nginx*', }); }); - describe('Can be sorted', () => { - it('Ascending', async () => { - const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); - const results = await getDataStreamsStats({ - esClient: esClientMock, - type: 'logs', - sortOrder: 'asc', - }); - expect(results.items[0].name).toBe('logs-elastic_agent-default'); - }); - it('Descending', async () => { - const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); - const results = await getDataStreamsStats({ - esClient: esClientMock, - type: 'logs', - sortOrder: 'desc', - }); - expect(results.items[0].name).toBe('logs-test.test-default'); - }); - }); it('Formats the items correctly', async () => { const esClientMock = elasticsearchServiceMock.createElasticsearchClient(); const results = await getDataStreamsStats({ esClient: esClientMock, type: 'logs', - sortOrder: 'desc', }); - expect(results.items).toEqual([ + expect(results.items.sort()).toEqual([ { - name: 'logs-test.test-default', - size: '6.2mb', - size_bytes: 6570447, - last_activity: 1698913802000, + name: 'logs-elastic_agent-default', + size: '1gb', + size_bytes: 1170805528, + last_activity: 1698916071000, }, { - name: 'logs-elastic_agent.metricbeat-default', - size: '1.6mb', - size_bytes: 1704807, - last_activity: 1698672046707, + name: 'logs-elastic_agent.filebeat-default', + size: '1.3mb', + size_bytes: 1459100, + last_activity: 1698902209996, }, { name: 'logs-elastic_agent.fleet_server-default', @@ -117,16 +95,16 @@ describe('getDataStreams', () => { last_activity: 1698914110010, }, { - name: 'logs-elastic_agent.filebeat-default', - size: '1.3mb', - size_bytes: 1459100, - last_activity: 1698902209996, + name: 'logs-elastic_agent.metricbeat-default', + size: '1.6mb', + size_bytes: 1704807, + last_activity: 1698672046707, }, { - name: 'logs-elastic_agent-default', - size: '1gb', - size_bytes: 1170805528, - last_activity: 1698916071000, + name: 'logs-test.test-default', + size: '6.2mb', + size_bytes: 6570447, + last_activity: 1698913802000, }, ]); }); diff --git a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts index 2f0f8057cdde..9ec252d09635 100644 --- a/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts +++ b/x-pack/plugins/dataset_quality/server/routes/data_streams/get_data_streams_stats/index.ts @@ -13,9 +13,8 @@ export async function getDataStreamsStats(options: { esClient: ElasticsearchClient; type?: DataStreamTypes; datasetQuery?: string; - sortOrder: 'asc' | 'desc'; }) { - const { esClient, type, datasetQuery, sortOrder } = options; + const { esClient, type, datasetQuery } = options; const matchingDataStreamsStats = await dataStreamService.getMatchingDataStreamsStats(esClient, { type: type ?? '*', @@ -31,15 +30,7 @@ export async function getDataStreamsStats(options: { }; }); - const sortedDataStreams = mappedDataStreams.sort((a, b) => { - if (sortOrder === 'desc') { - return b.name.localeCompare(a.name); - } - - return a.name.localeCompare(b.name); - }); - return { - items: sortedDataStreams, + items: mappedDataStreams, }; } diff --git a/x-pack/plugins/dataset_quality/server/routes/data_streams/routes.ts b/x-pack/plugins/dataset_quality/server/routes/data_streams/routes.ts index f973211cc734..4217b9711226 100644 --- a/x-pack/plugins/dataset_quality/server/routes/data_streams/routes.ts +++ b/x-pack/plugins/dataset_quality/server/routes/data_streams/routes.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { keyBy, merge, values } from 'lodash'; -import { dataStreamTypesRt, sortOrderRt } from '../../types/api_types'; +import { dataStreamTypesRt } from '../../../common/data_streams'; import { DataStreamsStatResponse } from '../../types/data_stream'; import { createDatasetQualityServerRoute } from '../create_datasets_quality_server_route'; import { getDataStreams } from './get_data_streams'; @@ -21,19 +21,22 @@ const statsRoute = createDatasetQualityServerRoute({ t.partial({ datasetQuery: t.string, }), - sortOrderRt, ]), }), options: { tags: [], }, async handler(resources): Promise { - const { context, params } = resources; + const { context, params, plugins } = resources; const coreContext = await context.core; // Query datastreams as the current user as the Kibana internal user may not have all the required permissions const esClient = coreContext.elasticsearch.client.asCurrentUser; + const fleetPluginStart = await plugins.fleet.start(); + const packageClient = fleetPluginStart.packageService.asInternalUser; + const packages = await packageClient.getPackages(); + const [dataStreams, dataStreamsStats] = await Promise.all([ getDataStreams({ esClient, @@ -43,8 +46,22 @@ const statsRoute = createDatasetQualityServerRoute({ getDataStreamsStats({ esClient, ...params.query }), ]); + const installedPackages = dataStreams.items.map((item) => item.integration); + + const integrations = packages + .filter((pkg) => installedPackages.includes(pkg.name)) + .map((p) => ({ + name: p.name, + title: p.title, + version: p.version, + icons: p.icons, + })); + return { - items: values(merge(keyBy(dataStreams.items, 'name'), keyBy(dataStreamsStats.items, 'name'))), + dataStreamsStats: values( + merge(keyBy(dataStreams.items, 'name'), keyBy(dataStreamsStats.items, 'name')) + ), + integrations, }; }, }); diff --git a/x-pack/plugins/dataset_quality/server/types.ts b/x-pack/plugins/dataset_quality/server/types.ts index f9a184cfb768..3874040f5d3b 100644 --- a/x-pack/plugins/dataset_quality/server/types.ts +++ b/x-pack/plugins/dataset_quality/server/types.ts @@ -6,12 +6,15 @@ */ import { CustomRequestHandlerContext } from '@kbn/core/server'; +import { FleetSetupContract, FleetStartContract } from '@kbn/fleet-plugin/server'; -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DatasetQualityPluginSetupDependencies {} +export interface DatasetQualityPluginSetupDependencies { + fleet: FleetSetupContract; +} -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface DatasetQualityPluginStartDependencies {} +export interface DatasetQualityPluginStartDependencies { + fleet: FleetStartContract; +} // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface DatasetQualityPluginSetup {} diff --git a/x-pack/plugins/dataset_quality/server/types/data_stream.ts b/x-pack/plugins/dataset_quality/server/types/data_stream.ts index 582746755ac5..423d85985c59 100644 --- a/x-pack/plugins/dataset_quality/server/types/data_stream.ts +++ b/x-pack/plugins/dataset_quality/server/types/data_stream.ts @@ -6,9 +6,11 @@ */ import { ByteSize } from '@elastic/elasticsearch/lib/api/types'; +import { Integration } from './integration'; export interface DataStreamsStatResponse { - items: DataStreamStat[]; + dataStreamsStats: DataStreamStat[]; + integrations: Integration[]; } export interface DataStreamStat { @@ -16,10 +18,7 @@ export interface DataStreamStat { size?: ByteSize; size_bytes?: number; last_activity?: number; - integration?: { - name?: string; - managed_by?: string; - }; + integration?: Integration; } export type DataStreamTypes = 'logs' | 'metrics' | 'traces' | 'synthetics' | 'profiling'; diff --git a/x-pack/plugins/dataset_quality/server/types/integration.ts b/x-pack/plugins/dataset_quality/server/types/integration.ts new file mode 100644 index 000000000000..2595a120c8b7 --- /dev/null +++ b/x-pack/plugins/dataset_quality/server/types/integration.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. + */ + +export interface Integration { + name: string; + title?: string; + version?: string; + icons?: IntegrationIcon[]; +} + +export interface IntegrationIcon { + path: string; + src: string; + title?: string; + size?: string; + type?: string; +} diff --git a/x-pack/plugins/dataset_quality/tsconfig.json b/x-pack/plugins/dataset_quality/tsconfig.json index 8e3ebcdb7e74..32baf4671143 100644 --- a/x-pack/plugins/dataset_quality/tsconfig.json +++ b/x-pack/plugins/dataset_quality/tsconfig.json @@ -11,10 +11,19 @@ ], "kbn_references": [ "@kbn/core", - "@kbn/server-route-repository", "@kbn/core-plugins-server", "@kbn/core-elasticsearch-server-mocks", + "@kbn/deeplinks-observability", + "@kbn/fleet-plugin", + "@kbn/observability-shared-plugin", + "@kbn/server-route-repository", + "@kbn/share-plugin", "@kbn/std", + "@kbn/i18n", + "@kbn/kibana-react-plugin", + "@kbn/i18n-react", + "@kbn/field-formats-plugin", + "@kbn/field-types" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx index 37a7c7153586..d1056fe8395e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx @@ -37,7 +37,7 @@ import { InferenceConfiguration } from './inference_config'; import { EMPTY_PIPELINE_CONFIGURATION, MLInferenceLogic } from './ml_inference_logic'; import { MlModelSelectOption } from './model_select_option'; import { PipelineSelectOption } from './pipeline_select_option'; -import { TextExpansionCallOut } from './text_expansion_callout'; +import { TextExpansionCallOut } from './text_expansion_callout/text_expansion_callout'; import { MODEL_REDACTED_VALUE, MODEL_SELECT_PLACEHOLDER } from './utils'; const MODEL_SELECT_PLACEHOLDER_VALUE = 'model_placeholder$$'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.test.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.test.tsx index 356de3acc9dc..6e5e2cb3fbbb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.tsx similarity index 98% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.tsx index ef7dd486e5eb..594ec2c6b451 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/deploy_model.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/deploy_model.tsx @@ -21,7 +21,7 @@ import { import { i18n } from '@kbn/i18n'; import { FormattedMessage, FormattedHTMLMessage } from '@kbn/i18n-react'; -import { docLinks } from '../../../../../shared/doc_links'; +import { docLinks } from '../../../../../../shared/doc_links'; import { TextExpansionCallOutState, TextExpansionDismissButton } from './text_expansion_callout'; import { TextExpansionCalloutLogic } from './text_expansion_callout_logic'; @@ -55,7 +55,7 @@ export const DeployModel = ({

    {i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.title', - { defaultMessage: 'Improve your results with ELSER v2' } + { defaultMessage: 'Improve your results with ELSER' } )}

    diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.test.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.test.tsx index a17eae3ef75f..84172ce34ccc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.tsx index 50d8ea47fb8f..fe8f0b7953c7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployed.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployed.tsx @@ -51,7 +51,7 @@ export const ModelDeployed = ({

    {i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployedTitle', - { defaultMessage: 'Your ELSER v2 model has deployed but not started.' } + { defaultMessage: 'Your ELSER model has deployed but not started.' } )}

    diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.test.tsx similarity index 94% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.test.tsx index f147778539f5..e2493fad0e4c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.tsx similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.tsx index 8804f4ec5843..f9b943983325 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_deployment_in_progress.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_deployment_in_progress.tsx @@ -28,7 +28,7 @@ export const ModelDeploymentInProgress = ({

    {i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployingTitle', - { defaultMessage: 'Your ELSER v2 model is deploying.' } + { defaultMessage: 'Your ELSER model is deploying.' } )}

    diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.test.tsx similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.test.tsx index c98ca42a4112..e5bf09b61e41 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.tsx similarity index 88% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.tsx index fa5a46d43804..1a15b8e96ab3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/model_started.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/model_started.tsx @@ -17,14 +17,15 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { KibanaLogic } from '../../../../../shared/kibana'; +import { KibanaLogic } from '../../../../../../shared/kibana'; + +import { TRAINED_MODELS_PATH } from '../utils'; import { TextExpansionCallOutState, TextExpansionDismissButton, FineTuneModelsButton, } from './text_expansion_callout'; -import { TRAINED_MODELS_PATH } from './utils'; export const ModelStarted = ({ dismiss, @@ -49,20 +50,20 @@ export const ModelStarted = ({ ? isCompact ? i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitleCompact', - { defaultMessage: 'Your ELSER v2 model is running single-threaded.' } + { defaultMessage: 'Your ELSER model is running single-threaded.' } ) : i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitle', - { defaultMessage: 'Your ELSER v2 model has started single-threaded.' } + { defaultMessage: 'Your ELSER model has started single-threaded.' } ) : isCompact ? i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitleCompact', - { defaultMessage: 'Your ELSER v2 model is running.' } + { defaultMessage: 'Your ELSER model is running.' } ) : i18n.translate( 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitle', - { defaultMessage: 'Your ELSER v2 model has started.' } + { defaultMessage: 'Your ELSER model has started.' } )} @@ -91,7 +92,7 @@ export const ModelStarted = ({ 'xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedBody', { defaultMessage: - 'Enjoy the power of ELSER v2 in your custom Inference pipeline.', + 'Enjoy the power of ELSER in your custom Inference pipeline.', } )}

    diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.test.tsx similarity index 97% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.test.tsx index 1ef7480b25c8..4abd583e4a79 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.tsx similarity index 95% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.tsx index 310f8f273a2c..1ea2c63ccaaa 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout.tsx @@ -12,8 +12,10 @@ import { useValues } from 'kea'; import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { KibanaLogic } from '../../../../../shared/kibana'; -import { IndexViewLogic } from '../../index_view_logic'; +import { KibanaLogic } from '../../../../../../shared/kibana'; +import { IndexViewLogic } from '../../../index_view_logic'; + +import { TRAINED_MODELS_PATH } from '../utils'; import { DeployModel } from './deploy_model'; import { ModelDeployed } from './model_deployed'; @@ -22,7 +24,6 @@ import { ModelStarted } from './model_started'; import { useTextExpansionCallOutData } from './text_expansion_callout_data'; import { TextExpansionCalloutLogic } from './text_expansion_callout_logic'; import { TextExpansionErrors } from './text_expansion_errors'; -import { TRAINED_MODELS_PATH } from './utils'; export interface TextExpansionCallOutState { dismiss: () => void; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_data.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_data.tsx similarity index 96% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_data.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_data.tsx index 849bcd7964f7..4cddec9b7d2d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_data.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_data.tsx @@ -9,7 +9,7 @@ import { useCallback, useEffect, useState } from 'react'; import { useValues } from 'kea'; -import { IndexViewLogic } from '../../index_view_logic'; +import { IndexViewLogic } from '../../../index_view_logic'; import { TextExpansionCallOutProps, TextExpansionCallOutState } from './text_expansion_callout'; import { TextExpansionCalloutLogic } from './text_expansion_callout_logic'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.test.ts similarity index 94% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.test.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.test.ts index e39230ee2b69..1380e05e4c57 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.test.ts @@ -5,15 +5,15 @@ * 2.0. */ -import { LogicMounter } from '../../../../../__mocks__/kea_logic'; +import { LogicMounter } from '../../../../../../__mocks__/kea_logic'; import { HttpResponse } from '@kbn/core/public'; -import { ErrorResponse, HttpError, Status } from '../../../../../../../common/types/api'; -import { MlModelDeploymentState } from '../../../../../../../common/types/ml'; -import { CreateTextExpansionModelApiLogic } from '../../../../api/ml_models/text_expansion/create_text_expansion_model_api_logic'; -import { FetchTextExpansionModelApiLogic } from '../../../../api/ml_models/text_expansion/fetch_text_expansion_model_api_logic'; -import { StartTextExpansionModelApiLogic } from '../../../../api/ml_models/text_expansion/start_text_expansion_model_api_logic'; +import { ErrorResponse, HttpError, Status } from '../../../../../../../../common/types/api'; +import { MlModelDeploymentState } from '../../../../../../../../common/types/ml'; +import { CreateTextExpansionModelApiLogic } from '../../../../../api/ml_models/text_expansion/create_text_expansion_model_api_logic'; +import { FetchTextExpansionModelApiLogic } from '../../../../../api/ml_models/text_expansion/fetch_text_expansion_model_api_logic'; +import { StartTextExpansionModelApiLogic } from '../../../../../api/ml_models/text_expansion/start_text_expansion_model_api_logic'; import { getTextExpansionError, @@ -80,19 +80,19 @@ describe('TextExpansionCalloutLogic', () => { }); it('uses the correct title and message from a create error', () => { expect(getTextExpansionError(error, undefined, undefined)).toEqual({ - title: 'Error with ELSER v2 deployment', + title: 'Error with ELSER deployment', message: error.body?.message, }); }); it('uses the correct title and message from a fetch error', () => { expect(getTextExpansionError(undefined, error, undefined)).toEqual({ - title: 'Error fetching ELSER v2 model', + title: 'Error fetching ELSER model', message: error.body?.message, }); }); it('uses the correct title and message from a start error', () => { expect(getTextExpansionError(undefined, undefined, error)).toEqual({ - title: 'Error starting ELSER v2 deployment', + title: 'Error starting ELSER deployment', message: error.body?.message, }); }); @@ -303,7 +303,7 @@ describe('TextExpansionCalloutLogic', () => { describe('textExpansionError', () => { const error = { body: { - error: 'Error with ELSER v2 deployment', + error: 'Error with ELSER deployment', message: 'Mocked error message', statusCode: 500, }, @@ -318,21 +318,21 @@ describe('TextExpansionCalloutLogic', () => { it('returns extracted error for create', () => { CreateTextExpansionModelApiLogic.actions.apiError(error); expect(TextExpansionCalloutLogic.values.textExpansionError).toStrictEqual({ - title: 'Error with ELSER v2 deployment', + title: 'Error with ELSER deployment', message: 'Mocked error message', }); }); it('returns extracted error for fetch', () => { FetchTextExpansionModelApiLogic.actions.apiError(error); expect(TextExpansionCalloutLogic.values.textExpansionError).toStrictEqual({ - title: 'Error fetching ELSER v2 model', + title: 'Error fetching ELSER model', message: 'Mocked error message', }); }); it('returns extracted error for start', () => { StartTextExpansionModelApiLogic.actions.apiError(error); expect(TextExpansionCalloutLogic.values.textExpansionError).toStrictEqual({ - title: 'Error starting ELSER v2 deployment', + title: 'Error starting ELSER deployment', message: 'Mocked error message', }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.ts similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.ts rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.ts index e8e6913c38ce..06d4f553bbab 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_callout_logic.ts @@ -9,26 +9,26 @@ import { kea, MakeLogicType } from 'kea'; import { i18n } from '@kbn/i18n'; -import { HttpError, Status } from '../../../../../../../common/types/api'; -import { MlModelDeploymentState } from '../../../../../../../common/types/ml'; -import { getErrorsFromHttpResponse } from '../../../../../shared/flash_messages/handle_api_errors'; +import { HttpError, Status } from '../../../../../../../../common/types/api'; +import { MlModelDeploymentState } from '../../../../../../../../common/types/ml'; +import { getErrorsFromHttpResponse } from '../../../../../../shared/flash_messages/handle_api_errors'; -import { KibanaLogic } from '../../../../../shared/kibana'; +import { KibanaLogic } from '../../../../../../shared/kibana'; import { CreateTextExpansionModelApiLogic, CreateTextExpansionModelApiLogicActions, CreateTextExpansionModelResponse, -} from '../../../../api/ml_models/text_expansion/create_text_expansion_model_api_logic'; +} from '../../../../../api/ml_models/text_expansion/create_text_expansion_model_api_logic'; import { FetchTextExpansionModelApiLogic, FetchTextExpansionModelApiLogicActions, FetchTextExpansionModelResponse, -} from '../../../../api/ml_models/text_expansion/fetch_text_expansion_model_api_logic'; +} from '../../../../../api/ml_models/text_expansion/fetch_text_expansion_model_api_logic'; import { StartTextExpansionModelApiLogic, StartTextExpansionModelApiLogicActions, -} from '../../../../api/ml_models/text_expansion/start_text_expansion_model_api_logic'; +} from '../../../../../api/ml_models/text_expansion/start_text_expansion_model_api_logic'; const FETCH_TEXT_EXPANSION_MODEL_POLLING_DURATION = 5000; // 5 seconds const FETCH_TEXT_EXPANSION_MODEL_POLLING_DURATION_ON_FAILURE = 30000; // 30 seconds @@ -97,7 +97,7 @@ export const getTextExpansionError = ( title: i18n.translate( 'xpack.enterpriseSearch.content.indices.pipelines.textExpansionCreateError.title', { - defaultMessage: 'Error with ELSER v2 deployment', + defaultMessage: 'Error with ELSER deployment', } ), message: getErrorsFromHttpResponse(createError)[0], @@ -107,7 +107,7 @@ export const getTextExpansionError = ( title: i18n.translate( 'xpack.enterpriseSearch.content.indices.pipelines.textExpansionStartError.title', { - defaultMessage: 'Error starting ELSER v2 deployment', + defaultMessage: 'Error starting ELSER deployment', } ), message: getErrorsFromHttpResponse(startError)[0], @@ -117,7 +117,7 @@ export const getTextExpansionError = ( title: i18n.translate( 'xpack.enterpriseSearch.content.indices.pipelines.textExpansionFetchError.title', { - defaultMessage: 'Error fetching ELSER v2 model', + defaultMessage: 'Error fetching ELSER model', } ), message: getErrorsFromHttpResponse(fetchError)[0], diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.test.tsx similarity index 93% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.test.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.test.tsx index cb15c2c5c541..2a7a6ea610bd 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { setMockValues } from '../../../../../__mocks__/kea_logic'; +import { setMockValues } from '../../../../../../__mocks__/kea_logic'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.tsx similarity index 84% rename from x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.tsx rename to x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.tsx index a46105586af1..e55f6109c177 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_errors.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/text_expansion_callout/text_expansion_errors.tsx @@ -13,10 +13,10 @@ import { EuiCallOut, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { HttpLogic } from '../../../../../shared/http'; +import { HttpLogic } from '../../../../../../shared/http'; -import { SendEnterpriseSearchTelemetry } from '../../../../../shared/telemetry'; -import { ML_NOTIFICATIONS_PATH } from '../../../../routes'; +import { SendEnterpriseSearchTelemetry } from '../../../../../../shared/telemetry'; +import { ML_NOTIFICATIONS_PATH } from '../../../../../routes'; export const TextExpansionErrors = ({ error }: { error: { title: string; message: string } }) => { const { http } = useValues(HttpLogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx index 6d3ad46a985c..718138535afb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference_pipeline_processors_card.tsx @@ -18,7 +18,7 @@ import { IndexNameLogic } from '../index_name_logic'; import { InferencePipelineCard } from './inference_pipeline_card'; import { AddMLInferencePipelineButton } from './ml_inference/add_ml_inference_button'; -import { TextExpansionCallOut } from './ml_inference/text_expansion_callout'; +import { TextExpansionCallOut } from './ml_inference/text_expansion_callout/text_expansion_callout'; import { PipelinesLogic } from './pipelines_logic'; export const MlInferencePipelineProcessorsCard: React.FC = () => { diff --git a/x-pack/plugins/fleet/cypress/tasks/common.ts b/x-pack/plugins/fleet/cypress/tasks/common.ts index ebb631b310b1..6d922f6b003f 100644 --- a/x-pack/plugins/fleet/cypress/tasks/common.ts +++ b/x-pack/plugins/fleet/cypress/tasks/common.ts @@ -49,6 +49,7 @@ export const request = ({ const NEW_FEATURES_TOUR_STORAGE_KEYS = { RULE_MANAGEMENT_PAGE: 'securitySolution.rulesManagementPage.newFeaturesTour.v8.9', + TIMELINES: 'securitySolution.security.timelineFlyoutHeader.saveTimelineTour', }; const disableNewFeaturesTours = (window: Window) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx index 0346986f3abb..62732c12d189 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx @@ -322,7 +322,7 @@ export const EditOutputFlyout: React.FunctionComponent = case outputType.Elasticsearch: return i18n.translate('xpack.fleet.settings.editOutputFlyout.esOutputTypeCallout', { defaultMessage: - 'This output type does not support connectivity to a remote Elasticsearch cluster, please the Remote Elasticsearch type for that.', + 'This output type does not support connectivity to a remote Elasticsearch cluster, please use the Remote Elasticsearch type for that.', }); } }; @@ -335,7 +335,7 @@ export const EditOutputFlyout: React.FunctionComponent = defaultMessage="Enter your output hosts, service token for your remote cluster, and any advanced YAML configuration. Learn more about how to use these parameters in {doc}." values={{ doc: ( - + {i18n.translate('xpack.fleet.settings.editOutputFlyout.docLabel', { defaultMessage: 'our documentation', })} diff --git a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts index 8bd0f823cb5c..10d8c7560b26 100644 --- a/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts +++ b/x-pack/plugins/fleet/server/services/elastic_agent_manifest.ts @@ -368,7 +368,7 @@ spec: value: "1" # Set to true to communicate with Fleet with either insecure HTTP or unverified HTTPS - name: FLEET_INSECURE - value: "true" + value: "false" # Fleet Server URL to enroll the Elastic Agent into # FLEET_URL can be found in Kibana, go to Management > Fleet > Settings - name: FLEET_URL @@ -393,7 +393,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.name - # The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac. + # The following ELASTIC_NETINFO:false variable will disable the netinfo.enabled option of add-host-metadata processor. This will remove fields host.ip and host.mac. # For more info: https://www.elastic.co/guide/en/beats/metricbeat/current/add-host-metadata.html - name: ELASTIC_NETINFO value: "false" diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index d65d8de5a382..2e67c70874e4 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -535,7 +535,7 @@ export function prepareTemplate({ const validFields = processFields(fields); - const mappings = generateMappings(validFields); + const mappings = generateMappings(validFields, isIndexModeTimeSeries); const templateName = generateTemplateName(dataStream); const templateIndexPattern = generateTemplateIndexPattern(dataStream); const templatePriority = getTemplatePriority(dataStream); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts index 96a2547c9e58..a621df33062a 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.test.ts @@ -897,7 +897,30 @@ describe('EPM template', () => { }; const fields: Field[] = safeLoad(literalYml); const processedFields = processFields(fields); - const mappings = generateMappings(processedFields); + const mappings = generateMappings(processedFields, true); + expect(mappings).toEqual(expectedMapping); + }); + + it('tests processing dimension field on a keyword - tsdb disabled', () => { + const literalYml = ` +- name: example.id + type: keyword + dimension: true + `; + const expectedMapping = { + properties: { + example: { + properties: { + id: { + type: 'keyword', + }, + }, + }, + }, + }; + const fields: Field[] = safeLoad(literalYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields, false); expect(mappings).toEqual(expectedMapping); }); @@ -921,7 +944,7 @@ describe('EPM template', () => { }; const fields: Field[] = safeLoad(literalYml); const processedFields = processFields(fields); - const mappings = generateMappings(processedFields); + const mappings = generateMappings(processedFields, true); expect(mappings).toEqual(expectedMapping); }); @@ -955,7 +978,40 @@ describe('EPM template', () => { }; const fields: Field[] = safeLoad(literalYml); const processedFields = processFields(fields); - const mappings = generateMappings(processedFields); + const mappings = generateMappings(processedFields, true); + expect(mappings).toEqual(expectedMapping); + }); + + it('tests processing metric_type field - tsdb disabled', () => { + const literalYml = ` +- name: total.norm.pct + type: scaled_float + metric_type: gauge + unit: percent + format: percent +`; + const expectedMapping = { + properties: { + total: { + properties: { + norm: { + properties: { + pct: { + scaling_factor: 1000, + type: 'scaled_float', + meta: { + unit: 'percent', + }, + }, + }, + }, + }, + }, + }, + }; + const fields: Field[] = safeLoad(literalYml); + const processedFields = processFields(fields); + const mappings = generateMappings(processedFields, false); expect(mappings).toEqual(expectedMapping); }); @@ -982,7 +1038,7 @@ describe('EPM template', () => { }; const fields: Field[] = safeLoad(literalYml); const processedFields = processFields(fields); - const mappings = generateMappings(processedFields); + const mappings = generateMappings(processedFields, true); expect(mappings).toEqual(expectedMapping); }); @@ -1292,7 +1348,7 @@ describe('EPM template', () => { }; const fields: Field[] = safeLoad(textWithRuntimeFieldsLiteralYml); const processedFields = processFields(fields); - const mappings = generateMappings(processedFields); + const mappings = generateMappings(processedFields, true); expect(mappings).toEqual(runtimeFieldMapping); }); 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 622538e15283..eb0ea4f62c73 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 @@ -141,46 +141,53 @@ const getBaseEsComponents = (type: string, isIndexModeTimeSeries: boolean): stri * * @param fields */ -export function generateMappings(fields: Field[]): IndexTemplateMappings { +export function generateMappings( + fields: Field[], + isIndexModeTimeSeries = false +): IndexTemplateMappings { const dynamicTemplates: Array> = []; const dynamicTemplateNames = new Set(); const runtimeFields: RuntimeFields = {}; - const { properties } = _generateMappings(fields, { - addDynamicMapping: (dynamicMapping: { - path: string; - matchingType: string; - pathMatch: string; - properties: Properties; - runtimeProperties?: Properties; - }) => { - const name = dynamicMapping.path; - if (dynamicTemplateNames.has(name)) { - return; - } + const { properties } = _generateMappings( + fields, + { + addDynamicMapping: (dynamicMapping: { + path: string; + matchingType: string; + pathMatch: string; + properties: Properties; + runtimeProperties?: Properties; + }) => { + const name = dynamicMapping.path; + if (dynamicTemplateNames.has(name)) { + return; + } - const dynamicTemplate: Properties = {}; - if (dynamicMapping.runtimeProperties !== undefined) { - dynamicTemplate.runtime = dynamicMapping.runtimeProperties; - } else { - dynamicTemplate.mapping = dynamicMapping.properties; - } + const dynamicTemplate: Properties = {}; + if (dynamicMapping.runtimeProperties !== undefined) { + dynamicTemplate.runtime = dynamicMapping.runtimeProperties; + } else { + dynamicTemplate.mapping = dynamicMapping.properties; + } - if (dynamicMapping.matchingType) { - dynamicTemplate.match_mapping_type = dynamicMapping.matchingType; - } + if (dynamicMapping.matchingType) { + dynamicTemplate.match_mapping_type = dynamicMapping.matchingType; + } - if (dynamicMapping.pathMatch) { - dynamicTemplate.path_match = dynamicMapping.pathMatch; - } + if (dynamicMapping.pathMatch) { + dynamicTemplate.path_match = dynamicMapping.pathMatch; + } - dynamicTemplateNames.add(name); - dynamicTemplates.push({ [dynamicMapping.path]: dynamicTemplate }); - }, - addRuntimeField: (runtimeField: { path: string; properties: Properties }) => { - runtimeFields[`${runtimeField.path}`] = runtimeField.properties; + dynamicTemplateNames.add(name); + dynamicTemplates.push({ [dynamicMapping.path]: dynamicTemplate }); + }, + addRuntimeField: (runtimeField: { path: string; properties: Properties }) => { + runtimeFields[`${runtimeField.path}`] = runtimeField.properties; + }, }, - }); + isIndexModeTimeSeries + ); const indexTemplateMappings: IndexTemplateMappings = { properties }; if (dynamicTemplates.length > 0) { @@ -206,7 +213,8 @@ function _generateMappings( addDynamicMapping: any; addRuntimeField: any; groupFieldName?: string; - } + }, + isIndexModeTimeSeries: boolean ): { properties: IndexTemplateMappings['properties']; hasNonDynamicTemplateMappings: boolean; @@ -294,7 +302,9 @@ function _generateMappings( case 'long': case 'boolean': dynProperties.type = field.object_type; - dynProperties.time_series_metric = field.metric_type; + if (isIndexModeTimeSeries) { + dynProperties.time_series_metric = field.metric_type; + } matchingType = field.object_type_mapping_type ?? field.object_type; default: break; @@ -359,7 +369,9 @@ function _generateMappings( case 'float': case 'half_float': dynProperties.type = field.object_type; - dynProperties.time_series_metric = field.metric_type; + if (isIndexModeTimeSeries) { + dynProperties.time_series_metric = field.metric_type; + } matchingType = field.object_type_mapping_type ?? 'double'; break; case 'byte': @@ -367,18 +379,24 @@ function _generateMappings( case 'short': case 'unsigned_long': dynProperties.type = field.object_type; - dynProperties.time_series_metric = field.metric_type; + if (isIndexModeTimeSeries) { + dynProperties.time_series_metric = field.metric_type; + } matchingType = field.object_type_mapping_type ?? 'long'; break; case 'integer': // Map integers as long, as in other cases. dynProperties.type = 'long'; - dynProperties.time_series_metric = field.metric_type; + if (isIndexModeTimeSeries) { + dynProperties.time_series_metric = field.metric_type; + } matchingType = field.object_type_mapping_type ?? 'long'; break; case 'boolean': dynProperties.type = field.object_type; - dynProperties.time_series_metric = field.metric_type; + if (isIndexModeTimeSeries) { + dynProperties.time_series_metric = field.metric_type; + } matchingType = field.object_type_mapping_type ?? field.object_type; break; case 'group': @@ -390,12 +408,16 @@ function _generateMappings( type: 'object', object_type: subField.object_type ?? subField.type, })); - const mappings = _generateMappings(subFields, { - ...ctx, - groupFieldName: ctx.groupFieldName - ? `${ctx.groupFieldName}.${field.name}` - : field.name, - }); + const mappings = _generateMappings( + subFields, + { + ...ctx, + groupFieldName: ctx.groupFieldName + ? `${ctx.groupFieldName}.${field.name}` + : field.name, + }, + isIndexModeTimeSeries + ); if (mappings.hasDynamicTemplateMappings) { hasDynamicTemplateMappings = true; } @@ -422,12 +444,16 @@ function _generateMappings( switch (type) { case 'group': - const mappings = _generateMappings(field.fields!, { - ...ctx, - groupFieldName: ctx.groupFieldName - ? `${ctx.groupFieldName}.${field.name}` - : field.name, - }); + const mappings = _generateMappings( + field.fields!, + { + ...ctx, + groupFieldName: ctx.groupFieldName + ? `${ctx.groupFieldName}.${field.name}` + : field.name, + }, + isIndexModeTimeSeries + ); if (mappings.hasNonDynamicTemplateMappings) { fieldProps = { properties: @@ -450,12 +476,16 @@ function _generateMappings( break; case 'group-nested': fieldProps = { - properties: _generateMappings(field.fields!, { - ...ctx, - groupFieldName: ctx.groupFieldName - ? `${ctx.groupFieldName}.${field.name}` - : field.name, - }).properties, + properties: _generateMappings( + field.fields!, + { + ...ctx, + groupFieldName: ctx.groupFieldName + ? `${ctx.groupFieldName}.${field.name}` + : field.name, + }, + isIndexModeTimeSeries + ).properties, ...generateNestedProps(field), type: 'nested', }; @@ -543,10 +573,10 @@ function _generateMappings( } } - if ('metric_type' in field) { + if ('metric_type' in field && isIndexModeTimeSeries) { fieldProps.time_series_metric = field.metric_type; } - if (field.dimension) { + if (field.dimension && isIndexModeTimeSeries) { fieldProps.time_series_dimension = field.dimension; } diff --git a/x-pack/plugins/fleet/server/services/epm/packages/install.ts b/x-pack/plugins/fleet/server/services/epm/packages/install.ts index 3a7fc7809615..a3919bbdb20e 100644 --- a/x-pack/plugins/fleet/server/services/epm/packages/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/packages/install.ts @@ -597,7 +597,9 @@ async function installPackageCommon(options: { return { assets, status: 'installed', installType, installSource }; }) .catch(async (err: Error) => { - logger.warn(`Failure to install package [${pkgName}]: [${err.toString()}]`); + logger.warn(`Failure to install package [${pkgName}]: [${err.toString()}]`, { + error: { stack_trace: err.stack }, + }); await handleInstallPackageFailure({ savedObjectsClient, error: err, diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index 350909d3de0a..2a76a9660778 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -255,10 +255,7 @@ export async function ensurePreconfiguredPackagesAndPolicies( ); }); - apm.startTransaction( - 'fleet.preconfiguration.addPackagePolicies.improved.prReview.50', - 'fleet' - ); + const s = apm.startSpan('Add preconfigured package policies', 'preconfiguration'); await addPreconfiguredPolicyPackages( soClient, esClient, @@ -267,7 +264,7 @@ export async function ensurePreconfiguredPackagesAndPolicies( defaultOutput, true ); - apm.endTransaction('fleet.preconfiguration.addPackagePolicies.improved.prReview.50'); + s?.end(); // Add the is_managed flag after configuring package policies to avoid errors if (shouldAddIsManagedFlag) { diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 270cfefb56a8..178499011bc6 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -6,6 +6,7 @@ */ import fs from 'fs/promises'; +import apm from 'elastic-apm-node'; import { compact } from 'lodash'; import pMap from 'p-map'; @@ -61,7 +62,17 @@ export async function setupFleet( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient ): Promise { - return awaitIfPending(async () => createSetupSideEffects(soClient, esClient)); + const t = apm.startTransaction('fleet-setup', 'fleet'); + + try { + return await awaitIfPending(async () => createSetupSideEffects(soClient, esClient)); + } catch (error) { + apm.captureError(error); + t.setOutcome('failure'); + throw error; + } finally { + t.end(); + } } async function createSetupSideEffects( @@ -113,7 +124,9 @@ async function createSetupSideEffects( const defaultOutput = await outputService.ensureDefaultOutput(soClient, esClient); logger.debug('Setting up Fleet Elasticsearch assets'); + let stepSpan = apm.startSpan('Install Fleet global assets', 'preconfiguration'); await ensureFleetGlobalEsAssets(soClient, esClient); + stepSpan?.end(); // Ensure that required packages are always installed even if they're left out of the config const preconfiguredPackageNames = new Set(packages.map((pkg) => pkg.name)); @@ -136,6 +149,7 @@ async function createSetupSideEffects( logger.debug('Setting up initial Fleet packages'); + stepSpan = apm.startSpan('Install preconfigured packages and policies', 'preconfiguration'); const { nonFatalErrors: preconfiguredPackagesNonFatalErrors } = await ensurePreconfiguredPackagesAndPolicies( soClient, @@ -146,17 +160,23 @@ async function createSetupSideEffects( defaultDownloadSource, DEFAULT_SPACE_ID ); + stepSpan?.end(); + stepSpan = apm.startSpan('Upgrade managed package policies', 'preconfiguration'); const packagePolicyUpgradeErrors = ( await upgradeManagedPackagePolicies(soClient, esClient) ).filter((result) => (result.errors ?? []).length > 0); + stepSpan?.end(); const nonFatalErrors = [...preconfiguredPackagesNonFatalErrors, ...packagePolicyUpgradeErrors]; logger.debug('Upgrade Fleet package install versions'); + stepSpan = apm.startSpan('Upgrade package install format version', 'preconfiguration'); await upgradePackageInstallVersion({ soClient, esClient, logger }); + stepSpan?.end(); logger.debug('Generating key pair for message signing'); + stepSpan = apm.startSpan('Configure message signing', 'preconfiguration'); if (!appContextService.getMessageSigningService()?.isEncryptionAvailable) { logger.warn( 'xpack.encryptedSavedObjects.encryptionKey is not configured, private key passphrase is being stored in plain text' @@ -176,16 +196,26 @@ async function createSetupSideEffects( logger.debug('Checking for and encrypting plain text uninstall tokens'); await appContextService.getUninstallTokenService()?.encryptTokens(); } + stepSpan?.end(); + stepSpan = apm.startSpan('Upgrade agent policy schema', 'preconfiguration'); logger.debug('Upgrade Agent policy schema version'); await upgradeAgentPolicySchemaVersion(soClient); + stepSpan?.end(); + stepSpan = apm.startSpan('Set up enrollment keys for preconfigured policies', 'preconfiguration'); logger.debug('Setting up Fleet enrollment keys'); await ensureDefaultEnrollmentAPIKeysExists(soClient, esClient); + stepSpan?.end(); if (nonFatalErrors.length > 0) { logger.info('Encountered non fatal errors during Fleet setup'); - formatNonFatalErrors(nonFatalErrors).forEach((error) => logger.info(JSON.stringify(error))); + formatNonFatalErrors(nonFatalErrors) + .map((e) => JSON.stringify(e)) + .forEach((error) => { + logger.info(error); + apm.captureError(error); + }); } logger.info('Fleet setup completed'); @@ -222,6 +252,7 @@ export async function ensureFleetGlobalEsAssets( esClient, installation, }).catch((err) => { + apm.captureError(err); logger.error( `Package needs to be manually reinstalled ${installation.name} after installing Fleet global assets: ${err.message}` ); diff --git a/x-pack/plugins/fleet/server/services/setup_utils.ts b/x-pack/plugins/fleet/server/services/setup_utils.ts index 4ac77e8e7d60..a9801e3470b7 100644 --- a/x-pack/plugins/fleet/server/services/setup_utils.ts +++ b/x-pack/plugins/fleet/server/services/setup_utils.ts @@ -12,7 +12,7 @@ let isPending = false; let onResolve = (value?: unknown) => {}; let onReject = (reason: any) => {}; -export async function awaitIfPending(asyncFunction: Function): Promise { +export async function awaitIfPending(asyncFunction: () => Promise): Promise { // pending successful or failed attempt if (isPending) { // don't run concurrent installs diff --git a/x-pack/plugins/index_management/common/constants/index.ts b/x-pack/plugins/index_management/common/constants/index.ts index a41f3d71bc6b..efe9630a5f23 100644 --- a/x-pack/plugins/index_management/common/constants/index.ts +++ b/x-pack/plugins/index_management/common/constants/index.ts @@ -10,6 +10,10 @@ export { API_BASE_PATH, INTERNAL_API_BASE_PATH } from './api_base_path'; export { INVALID_INDEX_PATTERN_CHARS, INVALID_TEMPLATE_NAME_CHARS } from './invalid_characters'; export * from './index_statuses'; +// Since each index can have a max length or 255 characters and the max length of +// the request is 4096 bytes we can fit a max of 16 indices in a single request. +export const MAX_INDICES_PER_REQUEST = 16; + export { UIM_APP_NAME, UIM_APP_LOAD, diff --git a/x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js b/x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js index 09c4988fc27b..f27c184afea6 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/clear_cache_indices.js @@ -27,8 +27,9 @@ export const clearCacheIndices = dispatch(reloadIndices(indexNames)); notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.clearCacheIndicesAction.successMessage', { - defaultMessage: 'Successfully cleared cache: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: + 'Successfully cleared cache for {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); }; diff --git a/x-pack/plugins/index_management/public/application/store/actions/close_indices.js b/x-pack/plugins/index_management/public/application/store/actions/close_indices.js index a9bedef283ec..368298a67137 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/close_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/close_indices.js @@ -25,8 +25,8 @@ export const closeIndices = dispatch(reloadIndices(indexNames)); notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage', { - defaultMessage: 'Successfully closed: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: 'Successfully closed {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); }; diff --git a/x-pack/plugins/index_management/public/application/store/actions/delete_indices.js b/x-pack/plugins/index_management/public/application/store/actions/delete_indices.js index 2a2f8f0b4109..1b082594f085 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/delete_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/delete_indices.js @@ -23,8 +23,8 @@ export const deleteIndices = } notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage', { - defaultMessage: 'Successfully deleted: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: 'Successfully deleted {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); dispatch(deleteIndicesSuccess({ indexNames })); diff --git a/x-pack/plugins/index_management/public/application/store/actions/flush_indices.js b/x-pack/plugins/index_management/public/application/store/actions/flush_indices.js index 83d4d5d46a3a..d033f5fbe343 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/flush_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/flush_indices.js @@ -26,8 +26,8 @@ export const flushIndices = dispatch(reloadIndices(indexNames)); notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage', { - defaultMessage: 'Successfully flushed: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: 'Successfully flushed {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); }; diff --git a/x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js b/x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js index bb3af529f404..d589ff6dd780 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/forcemerge_indices.js @@ -28,8 +28,9 @@ export const forcemergeIndices = i18n.translate( 'xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage', { - defaultMessage: 'Successfully force merged: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: + 'Successfully force merged {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, } ) ); diff --git a/x-pack/plugins/index_management/public/application/store/actions/open_indices.js b/x-pack/plugins/index_management/public/application/store/actions/open_indices.js index 8d4d0f728d16..53bb9186c2f9 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/open_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/open_indices.js @@ -26,8 +26,8 @@ export const openIndices = dispatch(reloadIndices(indexNames)); notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage', { - defaultMessage: 'Successfully opened: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: 'Successfully opened {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); }; diff --git a/x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js b/x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js index 56fe892393ea..574aa18c0282 100644 --- a/x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js +++ b/x-pack/plugins/index_management/public/application/store/actions/refresh_indices.js @@ -26,8 +26,8 @@ export const refreshIndices = dispatch(reloadIndices(indexNames)); notificationService.showSuccessToast( i18n.translate('xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage', { - defaultMessage: 'Successfully refreshed: [{indexNames}]', - values: { indexNames: indexNames.join(', ') }, + defaultMessage: 'Successfully refreshed {count, plural, one {# index} other {# indices} }', + values: { count: indexNames.length }, }) ); }; diff --git a/x-pack/plugins/index_management/server/routes/api/indices/helpers.test.ts b/x-pack/plugins/index_management/server/routes/api/indices/helpers.test.ts new file mode 100644 index 000000000000..fd44742d26e4 --- /dev/null +++ b/x-pack/plugins/index_management/server/routes/api/indices/helpers.test.ts @@ -0,0 +1,54 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IScopedClusterClient } from '@kbn/core/server'; + +import { executeAsyncByChunks } from './helpers'; + +const generateIndices = (count: number) => { + const indices = []; + + for (let i = 0; i < count; i++) { + indices.push(`index-${i}`); + } + + return indices; +}; + +const mockClient = { + asCurrentUser: { + indices: { + delete: jest.fn(), + }, + }, +} as unknown as IScopedClusterClient; + +describe('executeAsyncByChunks', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should make just one request for one index', async () => { + const params = { + index: generateIndices(1), + }; + + await executeAsyncByChunks(params, mockClient, 'delete'); + + expect(mockClient.asCurrentUser.indices.delete).toHaveBeenCalledTimes(1); + }); + + it('should make 2 requests for 32 indices', async () => { + const params = { + index: generateIndices(32), + }; + + await executeAsyncByChunks(params, mockClient, 'delete'); + + expect(mockClient.asCurrentUser.indices.delete).toHaveBeenCalledTimes(2); + }); +}); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/helpers.ts b/x-pack/plugins/index_management/server/routes/api/indices/helpers.ts new file mode 100644 index 000000000000..bb04cbd2c15c --- /dev/null +++ b/x-pack/plugins/index_management/server/routes/api/indices/helpers.ts @@ -0,0 +1,53 @@ +/* + * 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 { chunk } from 'lodash'; + +import type { IScopedClusterClient } from '@kbn/core/server'; +import { MAX_INDICES_PER_REQUEST } from '../../../../common/constants'; + +// To avoid having to to match method signatures with the client +// type, we use a generic CallableFn type. +type CallableFn = (args: Record) => Promise; + +export async function executeAsyncByChunks( + // Since we are using a key to access the index method, we need + // to use a generic type. + params: { + index: T[]; + format?: string; + expand_wildcards?: string; + max_num_segments?: number; + }, + dataClient: IScopedClusterClient, + methodName: keyof IScopedClusterClient['asCurrentUser']['indices'] +) { + const { index: indices, ...commonParams } = params; + + // When the number of indices is small, we can execute in a single request + // + // Otherwise we need to split the indices into chunks and execute them in multiple requests because + // if we try to execute an action with too many indices that account for a long string in the request + // ES will throw an error saying that the HTTP line is too large. + if (indices.length <= MAX_INDICES_PER_REQUEST) { + await (dataClient.asCurrentUser.indices[methodName] as CallableFn)({ + ...commonParams, + index: indices, + }); + } else { + const chunks = chunk(indices, MAX_INDICES_PER_REQUEST); + + await Promise.all( + chunks.map((chunkOfIndices) => + (dataClient.asCurrentUser.indices[methodName] as CallableFn)({ + ...commonParams, + index: chunkOfIndices, + }) + ) + ); + } +} diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts index a46a23b8fe47..bfedf6f4cb0c 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_clear_cache_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -28,7 +29,8 @@ export function registerClearCacheRoute({ router, lib: { handleEsError } }: Rout }; try { - await client.asCurrentUser.indices.clearCache(params); + await executeAsyncByChunks(params, client, 'clearCache'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts index 69d33b7fc799..b83c781f6457 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_close_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -28,7 +29,7 @@ export function registerCloseRoute({ router, lib: { handleEsError } }: RouteDepe }; try { - await client.asCurrentUser.indices.close(params); + await executeAsyncByChunks(params, client, 'close'); return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts index b72a2059beb1..b3931c1d5617 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_delete_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -22,13 +23,14 @@ export function registerDeleteRoute({ router, lib: { handleEsError } }: RouteDep const { indices = [] } = request.body as typeof bodySchema.type; const params = { - expand_wildcards: 'none' as const, format: 'json', + expand_wildcards: 'none' as const, index: indices, }; try { - await client.asCurrentUser.indices.delete(params); + await executeAsyncByChunks(params, client, 'delete'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts index cc07b92e7090..6ba8000306fe 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_flush_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -28,7 +29,8 @@ export function registerFlushRoute({ router, lib: { handleEsError } }: RouteDepe }; try { - await client.asCurrentUser.indices.flush(params); + await executeAsyncByChunks(params, client, 'flush'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts index af07a7371cf6..ffbe50598f19 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_forcemerge_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -36,7 +37,8 @@ export function registerForcemergeRoute({ router, lib: { handleEsError } }: Rout } try { - await client.asCurrentUser.indices.forcemerge(params); + await executeAsyncByChunks(params, client, 'forcemerge'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts index dde9e72af39d..9d0ae0a44b4e 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_open_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -28,7 +29,8 @@ export function registerOpenRoute({ router, lib: { handleEsError } }: RouteDepen }; try { - await client.asCurrentUser.indices.open(params); + await executeAsyncByChunks(params, client, 'open'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts index 2483cd534b80..c414a73cd73c 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_refresh_route.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { RouteDependencies } from '../../../types'; import { addBasePath } from '..'; +import { executeAsyncByChunks } from './helpers'; const bodySchema = schema.object({ indices: schema.arrayOf(schema.string()), @@ -28,7 +29,8 @@ export function registerRefreshRoute({ router, lib: { handleEsError } }: RouteDe }; try { - await client.asCurrentUser.indices.refresh(params); + await executeAsyncByChunks(params, client, 'refresh'); + return response.ok(); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts index 91a04187fc23..d64c6b1013d6 100644 --- a/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/indices/register_reload_route.ts @@ -5,8 +5,10 @@ * 2.0. */ +import { chunk } from 'lodash'; import { schema } from '@kbn/config-schema'; +import { MAX_INDICES_PER_REQUEST } from '../../../../common/constants'; import { RouteDependencies } from '../../../types'; import { fetchIndices } from '../../../lib/fetch_indices'; import { addBasePath } from '..'; @@ -30,7 +32,27 @@ export function registerReloadRoute({ const { indexNames = [] } = (request.body as typeof bodySchema.type) ?? {}; try { - const indices = await fetchIndices({ client, indexDataEnricher, config, indexNames }); + let indices; + + // When the number of indices is small, we can execute in a single request + // + // Otherwise we need to split the indices into chunks and execute them in multiple requests because + // if we try to execute an action with too many indices that account for a long string in the request + // ES will throw an error saying that the HTTP line is too large. + if (indexNames.length <= MAX_INDICES_PER_REQUEST) { + indices = await fetchIndices({ client, indexDataEnricher, config, indexNames }); + } else { + const chunks = chunk(indexNames, MAX_INDICES_PER_REQUEST); + + indices = ( + await Promise.all( + chunks.map((indexNamesChunk) => + fetchIndices({ client, indexDataEnricher, config, indexNames: indexNamesChunk }) + ) + ) + ).flat(); + } + return response.ok({ body: indices }); } catch (error) { return handleEsError({ error, response }); diff --git a/x-pack/plugins/infra/common/http_api/profiling_api.ts b/x-pack/plugins/infra/common/http_api/profiling_api.ts new file mode 100644 index 000000000000..3cf57ec0ef35 --- /dev/null +++ b/x-pack/plugins/infra/common/http_api/profiling_api.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const InfraProfilingRequestParamsRT = rt.type({ + hostname: rt.string, + timeRange: rt.type({ + from: rt.number, + to: rt.number, + }), +}); + +export type InfraProfilingRequestParams = rt.TypeOf; diff --git a/x-pack/plugins/infra/common/plugin_config_types.ts b/x-pack/plugins/infra/common/plugin_config_types.ts index 8f39680959bb..b69afe176cab 100644 --- a/x-pack/plugins/infra/common/plugin_config_types.ts +++ b/x-pack/plugins/infra/common/plugin_config_types.ts @@ -34,6 +34,7 @@ export interface InfraConfig { metricThresholdAlertRuleEnabled: boolean; logThresholdAlertRuleEnabled: boolean; alertsAndRulesDropdownEnabled: boolean; + profilingEnabled: boolean; }; } diff --git a/x-pack/plugins/infra/kibana.jsonc b/x-pack/plugins/infra/kibana.jsonc index b97a273b91f7..a5ffd146b618 100644 --- a/x-pack/plugins/infra/kibana.jsonc +++ b/x-pack/plugins/infra/kibana.jsonc @@ -35,7 +35,7 @@ "usageCollection", "visTypeTimeseries" ], - "optionalPlugins": ["spaces", "ml", "home", "embeddable", "osquery", "cloud"], + "optionalPlugins": ["spaces", "ml", "home", "embeddable", "osquery", "cloud", "profilingDataAccess"], "requiredBundles": [ "unifiedSearch", "observability", diff --git a/x-pack/plugins/infra/public/common/asset_details_config/asset_details_tabs.tsx b/x-pack/plugins/infra/public/common/asset_details_config/asset_details_tabs.tsx index 09e5cf268407..312ed7eb04a9 100644 --- a/x-pack/plugins/infra/public/common/asset_details_config/asset_details_tabs.tsx +++ b/x-pack/plugins/infra/public/common/asset_details_config/asset_details_tabs.tsx @@ -27,6 +27,12 @@ export const commonFlyoutTabs: Tab[] = [ defaultMessage: 'Processes', }), }, + { + id: ContentTabIds.PROFILING, + name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.profiling', { + defaultMessage: 'Universal Profiling', + }), + }, { id: ContentTabIds.LOGS, name: i18n.translate('xpack.infra.nodeDetails.tabs.logs.title', { diff --git a/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/asset_details/host/host_kpi_charts.ts b/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/asset_details/host/host_kpi_charts.ts index 9805fd317668..d72b2bee8a8e 100644 --- a/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/asset_details/host/host_kpi_charts.ts +++ b/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/asset_details/host/host_kpi_charts.ts @@ -10,7 +10,7 @@ import { hostLensFormulas } from '../../../formulas'; import { METRICS_TOOLTIP } from '../../translations'; import type { KPIChartProps } from '../../types'; -export const hostKPICharts: KPIChartProps[] = [ +export const hostKPICharts = (backgroundColor: string): KPIChartProps[] => [ { id: 'cpuUsage', title: i18n.translate('xpack.infra.assetDetailsEmbeddable.overview.kpi.cpuUsage.title', { @@ -29,7 +29,7 @@ export const hostKPICharts: KPIChartProps[] = [ : undefined, }, options: { - backgroundColor: '#F1D86F', + backgroundColor, showTrendLine: true, }, type: 'visualization', @@ -57,7 +57,7 @@ export const hostKPICharts: KPIChartProps[] = [ : undefined, }, options: { - backgroundColor: '#79AAD9', + backgroundColor, showTrendLine: true, }, type: 'visualization', @@ -82,7 +82,7 @@ export const hostKPICharts: KPIChartProps[] = [ : undefined, }, options: { - backgroundColor: '#A987D1', + backgroundColor, showTrendLine: true, }, type: 'visualization', @@ -107,7 +107,7 @@ export const hostKPICharts: KPIChartProps[] = [ : undefined, }, options: { - backgroundColor: '#F5A35C', + backgroundColor, showTrendLine: true, }, type: 'visualization', diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx index e779808347ec..e55a70978a74 100644 --- a/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx @@ -190,6 +190,7 @@ export const DecorateWithKibanaContext: DecoratorFn = (story) => { metricThresholdAlertRuleEnabled: true, logThresholdAlertRuleEnabled: true, alertsAndRulesDropdownEnabled: true, + profilingEnabled: false, }, }; diff --git a/x-pack/plugins/infra/public/components/asset_details/content/content.tsx b/x-pack/plugins/infra/public/components/asset_details/content/content.tsx index 9ffd94fcd9e7..49ad1cb87398 100644 --- a/x-pack/plugins/infra/public/components/asset_details/content/content.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/content/content.tsx @@ -9,7 +9,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React from 'react'; import { DatePicker } from '../date_picker/date_picker'; import { useTabSwitcherContext } from '../hooks/use_tab_switcher'; -import { Anomalies, Metadata, Processes, Osquery, Logs, Overview } from '../tabs'; +import { Anomalies, Metadata, Processes, Osquery, Logs, Overview, Profiling } from '../tabs'; import { ContentTabIds } from '../types'; export const Content = () => { @@ -22,6 +22,7 @@ export const Content = () => { ContentTabIds.LOGS, ContentTabIds.METADATA, ContentTabIds.PROCESSES, + ContentTabIds.PROFILING, ContentTabIds.ANOMALIES, ]} /> @@ -45,6 +46,9 @@ export const Content = () => { + + + ); diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts index 4b5ec03b3300..42abaf1c5bc9 100644 --- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_url_state.ts @@ -49,6 +49,7 @@ const TabIdRT = rt.union([ rt.literal(ContentTabIds.OVERVIEW), rt.literal(ContentTabIds.METADATA), rt.literal(ContentTabIds.PROCESSES), + rt.literal(ContentTabIds.PROFILING), rt.literal(ContentTabIds.LOGS), rt.literal(ContentTabIds.ANOMALIES), rt.literal(ContentTabIds.OSQUERY), diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx b/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx index a7e0b311d334..3fae1eca66a4 100644 --- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx @@ -113,8 +113,9 @@ const useFeatureFlagTabs = () => { const featureFlagControlledTabs: Partial> = useMemo( () => ({ [ContentTabIds.OSQUERY]: featureFlags.osqueryEnabled, + [ContentTabIds.PROFILING]: featureFlags.profilingEnabled, }), - [featureFlags.osqueryEnabled] + [featureFlags.osqueryEnabled, featureFlags.profilingEnabled] ); const isTabEnabled = useCallback( diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_profilling_flamegraph_data.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_profilling_flamegraph_data.ts new file mode 100644 index 000000000000..6ff433c11512 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_profilling_flamegraph_data.ts @@ -0,0 +1,50 @@ +/* + * 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 { useEffect } from 'react'; +import type { BaseFlameGraph } from '@kbn/profiling-utils'; +import type { Subject } from 'rxjs'; +import { + type InfraProfilingRequestParams, + InfraProfilingRequestParamsRT, +} from '../../../../common/http_api/profiling_api'; +import { useHTTPRequest } from '../../../hooks/use_http_request'; + +interface Props extends InfraProfilingRequestParams { + request$?: Subject<() => Promise>; + active: boolean; +} + +export function useProfilingFlamegraphData({ request$, active, ...params }: Props) { + const { loading, error, response, makeRequest } = useHTTPRequest( + '/api/infra/profiling/flamegraph', + 'POST', + JSON.stringify(InfraProfilingRequestParamsRT.encode(params)), + undefined, + undefined, + undefined, + true + ); + + useEffect(() => { + if (!active) { + return; + } + + if (request$) { + request$.next(makeRequest); + } else { + makeRequest(); + } + }, [active, makeRequest, request$]); + + return { + loading, + error, + response, + }; +} diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/index.ts b/x-pack/plugins/infra/public/components/asset_details/tabs/index.ts index 4a3cde85a3ca..779531d15910 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/index.ts +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/index.ts @@ -8,6 +8,7 @@ export { Anomalies } from './anomalies/anomalies'; export { Metadata } from './metadata/metadata'; export { Processes } from './processes/processes'; +export { Profiling } from './profiling/profiling'; export { Osquery } from './osquery/osquery'; export { Logs } from './logs/logs'; export { Overview } from './overview/overview'; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx index 034d6feaacfc..2a1395d7cf78 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import type { DataView } from '@kbn/data-views-plugin/public'; import type { TimeRange } from '@kbn/es-query'; +import { useTheme } from '@kbn/observability-shared-plugin/public'; import { assetDetailsDashboards, KPI_CHART_HEIGHT } from '../../../../../common/visualizations'; import { Kpi } from './kpi'; @@ -19,19 +20,23 @@ interface Props { } export const KPIGrid = ({ assetName, dataView, dateRange }: Props) => { + const euiTheme = useTheme(); + return ( - {assetDetailsDashboards.host.hostKPICharts.map((chartProps, index) => ( - - - - ))} + {assetDetailsDashboards.host + .hostKPICharts(euiTheme.eui.euiColorLightestShade) + .map((chartProps, index) => ( + + + + ))} ); }; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/profiling/profiling.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/profiling/profiling.tsx new file mode 100644 index 000000000000..ee6a86df9e89 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/profiling/profiling.tsx @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EmbeddableFlamegraph } from '@kbn/observability-shared-plugin/public'; +import { BaseFlameGraph } from '@kbn/profiling-utils'; +import { useAssetDetailsRenderPropsContext } from '../../hooks/use_asset_details_render_props'; +import { useDatePickerContext } from '../../hooks/use_date_picker'; +import { useProfilingFlamegraphData } from '../../hooks/use_profilling_flamegraph_data'; +import { useRequestObservable } from '../../hooks/use_request_observable'; +import { useTabSwitcherContext } from '../../hooks/use_tab_switcher'; +import { ContentTabIds } from '../../types'; + +export function Profiling() { + const { request$ } = useRequestObservable(); + const { asset } = useAssetDetailsRenderPropsContext(); + const { activeTabId } = useTabSwitcherContext(); + const { getDateRangeInTimestamp } = useDatePickerContext(); + const { loading, response } = useProfilingFlamegraphData({ + active: activeTabId === ContentTabIds.PROFILING, + request$, + hostname: asset.name, + timeRange: getDateRangeInTimestamp(), + }); + + return ; +} diff --git a/x-pack/plugins/infra/public/components/asset_details/types.ts b/x-pack/plugins/infra/public/components/asset_details/types.ts index 56f62a5ebc08..dd3ae9af9d62 100644 --- a/x-pack/plugins/infra/public/components/asset_details/types.ts +++ b/x-pack/plugins/infra/public/components/asset_details/types.ts @@ -21,6 +21,7 @@ export enum ContentTabIds { OVERVIEW = 'overview', METADATA = 'metadata', PROCESSES = 'processes', + PROFILING = 'profiling', ANOMALIES = 'anomalies', OSQUERY = 'osquery', LOGS = 'logs', diff --git a/x-pack/plugins/infra/public/containers/plugin_config_context.test.tsx b/x-pack/plugins/infra/public/containers/plugin_config_context.test.tsx index 43d4e8913564..1b9980bf5f17 100644 --- a/x-pack/plugins/infra/public/containers/plugin_config_context.test.tsx +++ b/x-pack/plugins/infra/public/containers/plugin_config_context.test.tsx @@ -28,6 +28,7 @@ describe('usePluginConfig()', () => { metricThresholdAlertRuleEnabled: true, logThresholdAlertRuleEnabled: true, alertsAndRulesDropdownEnabled: true, + profilingEnabled: false, }, }; const { result } = renderHook(() => usePluginConfig(), { diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/host_count_kpi.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/host_count_kpi.tsx index 22f07d829906..45e9f5f0b2c8 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/host_count_kpi.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/host_count_kpi.tsx @@ -6,6 +6,7 @@ */ import { i18n } from '@kbn/i18n'; import React from 'react'; +import { useTheme } from '@kbn/observability-shared-plugin/public'; import { hostLensFormulas, METRICS_TOOLTIP } from '../../../../../common/visualizations'; import { useHostCountContext } from '../../hooks/use_host_count'; import { useUnifiedSearchContext } from '../../hooks/use_unified_search'; @@ -13,17 +14,18 @@ import { useUnifiedSearchContext } from '../../hooks/use_unified_search'; import { type Props, MetricChartWrapper } from '../chart/metric_chart_wrapper'; import { TooltipContent } from '../../../../../components/lens'; -const HOSTS_CHART: Omit = { - id: 'hostsViewKPI-hostsCount', - color: '#6DCCB1', - title: i18n.translate('xpack.infra.hostsViewPage.kpi.hostCount.title', { - defaultMessage: 'Hosts', - }), -}; - export const HostCountKpi = ({ height }: { height: number }) => { const { data: hostCountData, isRequestRunning: hostCountLoading } = useHostCountContext(); const { searchCriteria } = useUnifiedSearchContext(); + const euiTheme = useTheme(); + + const hostsCountChart: Omit = { + id: 'hostsViewKPI-hostsCount', + color: euiTheme.eui.euiColorLightestShade, + title: i18n.translate('xpack.infra.hostsViewPage.kpi.hostCount.title', { + defaultMessage: 'Hosts', + }), + }; const getSubtitle = () => { return searchCriteria.limit < (hostCountData?.count.value ?? 0) @@ -38,7 +40,7 @@ export const HostCountKpi = ({ height }: { height: number }) => { return ( { + const euiTheme = useTheme(); + return ( @@ -23,11 +26,13 @@ export const KPIGrid = () => { - {assetDetailsDashboards.host.hostKPICharts.map((chartProp, index) => ( - - - - ))} + {assetDetailsDashboards.host + .hostKPICharts(euiTheme.eui.euiColorLightestShade) + .map((chartProp, index) => ( + + + + ))} ); diff --git a/x-pack/plugins/infra/server/infra_server.ts b/x-pack/plugins/infra/server/infra_server.ts index 66c65428833a..b041f495057a 100644 --- a/x-pack/plugins/infra/server/infra_server.ts +++ b/x-pack/plugins/infra/server/infra_server.ts @@ -32,6 +32,7 @@ import { initProcessListRoute } from './routes/process_list'; import { initSnapshotRoute } from './routes/snapshot'; import { initInfraMetricsRoute } from './routes/infra'; import { initMetricsExplorerViewRoutes } from './routes/metrics_explorer_views'; +import { initProfilingRoutes } from './routes/profiling'; export const initInfraServer = (libs: InfraBackendLibs) => { initIpToHostName(libs); @@ -59,4 +60,5 @@ export const initInfraServer = (libs: InfraBackendLibs) => { initProcessListRoute(libs); initOverviewRoute(libs); initInfraMetricsRoute(libs); + initProfilingRoutes(libs); }; diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts index 986a6a874951..a6bba3babfa8 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts @@ -27,6 +27,10 @@ import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server'; import { LogsSharedPluginSetup, LogsSharedPluginStart } from '@kbn/logs-shared-plugin/server'; import { VersionedRouteConfig } from '@kbn/core-http-server'; import { MetricsDataPluginSetup } from '@kbn/metrics-data-access-plugin/server'; +import { + ProfilingDataAccessPluginSetup, + ProfilingDataAccessPluginStart, +} from '@kbn/profiling-data-access-plugin/server'; export interface InfraServerPluginSetupDeps { alerting: AlertingPluginContract; @@ -42,12 +46,14 @@ export interface InfraServerPluginSetupDeps { ml?: MlPluginSetup; logsShared: LogsSharedPluginSetup; metricsDataAccess: MetricsDataPluginSetup; + profilingDataAccess?: ProfilingDataAccessPluginSetup; } export interface InfraServerPluginStartDeps { data: DataPluginStart; dataViews: DataViewsPluginStart; logsShared: LogsSharedPluginStart; + profilingDataAccess?: ProfilingDataAccessPluginStart; } export interface CallWithRequestParams extends estypes.RequestBase { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts index 81974728acc5..2c88148bc2fa 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.test.ts @@ -2272,6 +2272,7 @@ const createMockStaticConfiguration = (sources: any): InfraConfig => ({ metricThresholdAlertRuleEnabled: true, logThresholdAlertRuleEnabled: true, alertsAndRulesDropdownEnabled: true, + profilingEnabled: false, }, enabled: true, sources, diff --git a/x-pack/plugins/infra/server/lib/sources/sources.test.ts b/x-pack/plugins/infra/server/lib/sources/sources.test.ts index 27f232eed3c9..ef58e5a98577 100644 --- a/x-pack/plugins/infra/server/lib/sources/sources.test.ts +++ b/x-pack/plugins/infra/server/lib/sources/sources.test.ts @@ -101,6 +101,7 @@ const createMockStaticConfiguration = (): InfraConfig => ({ metricThresholdAlertRuleEnabled: true, logThresholdAlertRuleEnabled: true, alertsAndRulesDropdownEnabled: true, + profilingEnabled: false, }, enabled: true, }); diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index afcbe69c01f5..63bb40f66c32 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -112,6 +112,15 @@ export const config: PluginConfigDescriptor = { traditional: schema.boolean({ defaultValue: true }), serverless: schema.boolean({ defaultValue: true }), }), + /** + * This flag depends on profilingDataAccess optional plugin, + * make sure to enable it with `xpack.profiling.enabled: true` + * before enabling this flag. + */ + profilingEnabled: offeringBasedSchema({ + traditional: schema.boolean({ defaultValue: false }), + serverless: schema.boolean({ defaultValue: false }), + }), }), }), exposeToBrowser: publicConfigKeys, diff --git a/x-pack/plugins/infra/server/routes/profiling/index.ts b/x-pack/plugins/infra/server/routes/profiling/index.ts new file mode 100644 index 000000000000..4b268c35becf --- /dev/null +++ b/x-pack/plugins/infra/server/routes/profiling/index.ts @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; +import { decodeOrThrow } from '@kbn/io-ts-utils'; +import { InfraProfilingRequestParamsRT } from '../../../common/http_api/profiling_api'; +import type { InfraBackendLibs } from '../../lib/infra_types'; +import { fetchProfilingFlamegraph } from './lib/fetch_profiling_flamechart'; +import { fetchProfilingStatus } from './lib/fetch_profiling_status'; +import { getProfilingDataAccess } from './lib/get_profiling_data_access'; + +export function initProfilingRoutes({ framework, getStartServices, logger }: InfraBackendLibs) { + if (!Object.hasOwn(framework.plugins, 'profilingDataAccess')) { + logger.info( + "Skipping initialization of Profiling endpoints because 'profilingDataAccess' plugin is not available" + ); + return; + } + + framework.registerRoute( + { + method: 'get', + path: '/api/infra/profiling/status', + validate: false, + }, + async (requestContext, request, response) => { + const [coreRequestContext, infraRequestContext, profilingDataAccess] = await Promise.all([ + requestContext.core, + requestContext.infra, + getProfilingDataAccess(getStartServices), + ]); + + const profilingStatus = await fetchProfilingStatus( + profilingDataAccess, + coreRequestContext, + infraRequestContext + ); + + return response.ok({ + body: profilingStatus, + }); + } + ); + + framework.registerRoute( + { + method: 'post', + path: '/api/infra/profiling/flamegraph', + validate: { + /** + * Allow any body object and validate it inside + * the handler using RT. + */ + body: schema.object({}, { unknowns: 'allow' }), + }, + }, + async (requestContext, request, response) => { + const params = decodeOrThrow(InfraProfilingRequestParamsRT)(request.body); + + const [coreRequestContext, profilingDataAccess] = await Promise.all([ + requestContext.core, + getProfilingDataAccess(getStartServices), + ]); + + const flamegraph = await fetchProfilingFlamegraph( + params, + profilingDataAccess, + coreRequestContext + ); + + return response.ok({ + body: flamegraph, + }); + } + ); +} diff --git a/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_flamechart.ts b/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_flamechart.ts new file mode 100644 index 000000000000..593c9e761118 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_flamechart.ts @@ -0,0 +1,31 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoreRequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; +import type { ProfilingDataAccessPluginStart } from '@kbn/profiling-data-access-plugin/server'; +import type { BaseFlameGraph } from '@kbn/profiling-utils'; +import { profilingUseLegacyFlamegraphAPI } from '@kbn/observability-plugin/common'; +import type { InfraProfilingRequestParams } from '../../../../common/http_api/profiling_api'; +import { HOST_FIELD } from '../../../../common/constants'; + +export async function fetchProfilingFlamegraph( + { hostname, timeRange }: InfraProfilingRequestParams, + profilingDataAccess: ProfilingDataAccessPluginStart, + coreRequestContext: CoreRequestHandlerContext +): Promise { + const useLegacyFlamegraphAPI = await coreRequestContext.uiSettings.client.get( + profilingUseLegacyFlamegraphAPI + ); + + return await profilingDataAccess.services.fetchFlamechartData({ + esClient: coreRequestContext.elasticsearch.client.asCurrentUser, + rangeFromMs: timeRange.from, + rangeToMs: timeRange.to, + kuery: `${HOST_FIELD} : "${hostname}"`, + useLegacyFlamegraphAPI, + }); +} diff --git a/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_status.ts b/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_status.ts new file mode 100644 index 000000000000..3ef929eeef5a --- /dev/null +++ b/x-pack/plugins/infra/server/routes/profiling/lib/fetch_profiling_status.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 { CoreRequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; +import type { ProfilingDataAccessPluginStart } from '@kbn/profiling-data-access-plugin/server'; +import type { ProfilingStatus } from '@kbn/profiling-utils'; +import type { InfraRequestHandlerContext } from '../../../types'; + +export async function fetchProfilingStatus( + profilingDataAccess: ProfilingDataAccessPluginStart, + coreRequestContext: CoreRequestHandlerContext, + infraRequestContext: InfraRequestHandlerContext +): Promise { + return await profilingDataAccess.services.getStatus({ + esClient: coreRequestContext.elasticsearch.client, + soClient: coreRequestContext.savedObjects.client, + spaceId: infraRequestContext.spaceId, + }); +} diff --git a/x-pack/plugins/infra/server/routes/profiling/lib/get_profiling_data_access.ts b/x-pack/plugins/infra/server/routes/profiling/lib/get_profiling_data_access.ts new file mode 100644 index 000000000000..2e54b38b4c80 --- /dev/null +++ b/x-pack/plugins/infra/server/routes/profiling/lib/get_profiling_data_access.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 { ProfilingDataAccessPluginStart } from '@kbn/profiling-data-access-plugin/server'; +import type { InfraPluginStartServicesAccessor } from '../../../types'; + +export async function getProfilingDataAccess( + getStartServices: InfraPluginStartServicesAccessor +): Promise { + const [, { profilingDataAccess }] = await getStartServices(); + + if (profilingDataAccess === undefined) { + throw new Error( + "Trying to access profilingDataAccess plugin but it's not in the start dependencies" + ); + } + + return profilingDataAccess; +} diff --git a/x-pack/plugins/infra/tsconfig.json b/x-pack/plugins/infra/tsconfig.json index ea4fa7be6565..da026aa7d7e9 100644 --- a/x-pack/plugins/infra/tsconfig.json +++ b/x-pack/plugins/infra/tsconfig.json @@ -75,7 +75,10 @@ "@kbn/chart-icons", "@kbn/advanced-settings-plugin", "@kbn/cloud-plugin", - "@kbn/custom-icons" + "@kbn/custom-icons", + "@kbn/profiling-utils", + "@kbn/profiling-data-access-plugin", + "@kbn/core-http-request-handler-context-server" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts index d54cc4de89fa..267671a06265 100644 --- a/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts +++ b/x-pack/plugins/lens/common/expressions/datatable/datatable_column.ts @@ -45,6 +45,7 @@ export interface ColumnState { summaryRow?: 'none' | 'sum' | 'avg' | 'count' | 'min' | 'max'; summaryLabel?: string; collapseFn?: CollapseFunction; + isMetric?: boolean; } export type DatatableColumnResult = ColumnState & { type: 'lens_datatable_column' }; diff --git a/x-pack/plugins/lens/kibana.jsonc b/x-pack/plugins/lens/kibana.jsonc index 04bb96af5938..1813264f7ca5 100644 --- a/x-pack/plugins/lens/kibana.jsonc +++ b/x-pack/plugins/lens/kibana.jsonc @@ -56,6 +56,7 @@ "embeddable", "fieldFormats", "charts", + "textBasedLanguages", ], "extraPublicDirs": [ "common/constants" diff --git a/x-pack/plugins/lens/public/app_plugin/app.test.tsx b/x-pack/plugins/lens/public/app_plugin/app.test.tsx index 9f5a9eb6d5a4..83cc485e09c7 100644 --- a/x-pack/plugins/lens/public/app_plugin/app.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/app.test.tsx @@ -538,9 +538,10 @@ describe('Lens App', () => { } async function testSave(inst: ReactWrapper, saveProps: SaveProps) { - await getButton(inst).run(inst.getDOMNode()); - inst.update(); - const handler = inst.find('SavedObjectSaveModalOrigin').prop('onSave') as ( + getButton(inst).run(inst.getDOMNode()); + // wait a tick since SaveModalContainer initializes asynchronously + await new Promise(process.nextTick); + const handler = inst.update().find('SavedObjectSaveModalOrigin').prop('onSave') as ( p: unknown ) => void; handler(saveProps); diff --git a/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx b/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx index e01f68d9e4b3..83ae6cd66702 100644 --- a/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx +++ b/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx @@ -10,6 +10,7 @@ import { i18n } from '@kbn/i18n'; import { isFilterPinned } from '@kbn/es-query'; import { VisualizeFieldContext } from '@kbn/ui-actions-plugin/public'; import type { SavedObjectReference } from '@kbn/core/public'; +import { EuiLoadingSpinner } from '@elastic/eui'; import { SaveModal } from './save_modal'; import type { LensAppProps, LensAppServices } from './types'; import type { SaveProps } from './app'; @@ -58,6 +59,7 @@ export function SaveModalContainer({ let title = ''; let description; let savedObjectId; + const [initializing, setInitializing] = useState(true); const [lastKnownDoc, setLastKnownDoc] = useState(initLastKnownDoc); if (lastKnownDoc) { title = lastKnownDoc.title; @@ -92,9 +94,15 @@ export function SaveModalContainer({ getPersisted({ initialInput, lensServices, - }).then((persisted) => { - if (persisted?.doc && isMounted) setLastKnownDoc(persisted.doc); - }); + }) + .then((persisted) => { + if (persisted?.doc && isMounted) setLastKnownDoc(persisted.doc); + }) + .finally(() => { + setInitializing(false); + }); + } else { + setInitializing(false); } return () => { @@ -135,6 +143,10 @@ export function SaveModalContainer({ } }; + if (initializing) { + return ; + } + const savingToLibraryPermitted = Boolean(isSaveable && application.capabilities.visualize.save); return ( diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx new file mode 100644 index 000000000000..5f0abbf3a952 --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/flyout_wrapper.tsx @@ -0,0 +1,157 @@ +/* + * 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 { + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiFlyoutBody, + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiTitle, + EuiToolTip, + EuiButton, + EuiLink, + EuiBetaBadge, +} from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; +import { css } from '@emotion/react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import type { FlyoutWrapperProps } from './types'; + +export const FlyoutWrapper = ({ + children, + isInlineFlyoutVisible, + isScrollable, + displayFlyoutHeader, + language, + attributesChanged, + onCancel, + navigateToLensEditor, + onApply, +}: FlyoutWrapperProps) => { + return ( + <> + {isInlineFlyoutVisible && displayFlyoutHeader && ( + + + + +

    + {i18n.translate('xpack.lens.config.editVisualizationLabel', { + defaultMessage: 'Edit {lang} visualization', + values: { lang: language }, + })} + + + +

    +
    +
    + {navigateToLensEditor && ( + + + {i18n.translate('xpack.lens.config.editLinkLabel', { + defaultMessage: 'Edit in Lens', + })} + + + )} +
    +
    + )} + + * { + pointer-events: auto; + } + } + .euiFlyoutBody__overflowContent { + padding: 0; + block-size: 100%; + } + `} + > + {children} + + {isInlineFlyoutVisible && ( + + + + + + + + + + + + + + + )} + + ); +}; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.test.tsx index 34adf0c9c254..26428091032e 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.test.tsx @@ -39,11 +39,11 @@ describe('Lens flyout', () => { newDatasourceState: 'newDatasourceState', }) ); - expect(updaterFn).toHaveBeenCalledWith('newDatasourceState', null); + expect(updaterFn).toHaveBeenCalledWith('newDatasourceState', null, 'testVis'); store.dispatch( updateVisualizationState({ visualizationId: 'testVis', newState: 'newVisState' }) ); - expect(updaterFn).toHaveBeenCalledWith('newDatasourceState', 'newVisState'); + expect(updaterFn).toHaveBeenCalledWith('newDatasourceState', 'newVisState', 'testVis'); }); test('updater is not run if it does not modify visualization or datasource state', () => { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx index fc6511b66ec1..91b094c14116 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/get_edit_lens_configuration.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useState } from 'react'; import { EuiFlyout, EuiLoadingSpinner, EuiOverlayMask } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Provider } from 'react-redux'; @@ -25,16 +25,21 @@ import { } from '../../../state_management'; import { generateId } from '../../../id_generator'; import type { DatasourceMap, VisualizationMap } from '../../../types'; -import { - LensEditConfigurationFlyout, - type EditConfigPanelProps, -} from './lens_configuration_flyout'; +import { LensEditConfigurationFlyout } from './lens_configuration_flyout'; +import type { EditConfigPanelProps } from './types'; import { SavedObjectIndexStore, type Document } from '../../../persistence'; +import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; import { DOC_TYPE } from '../../../../common/constants'; export type EditLensConfigurationProps = Omit< EditConfigPanelProps, - 'startDependencies' | 'coreStart' | 'visualizationMap' | 'datasourceMap' | 'saveByRef' + | 'startDependencies' + | 'coreStart' + | 'visualizationMap' + | 'datasourceMap' + | 'saveByRef' + | 'setCurrentAttributes' + | 'previousAttributes' >; function LoadingSpinnerWithOverlay() { return ( @@ -44,7 +49,11 @@ function LoadingSpinnerWithOverlay() { ); } -type UpdaterType = (datasourceState: unknown, visualizationState: unknown) => void; +type UpdaterType = ( + datasourceState: unknown, + visualizationState: unknown, + visualizationType?: string +) => void; // exported for testing export const updatingMiddleware = @@ -68,7 +77,12 @@ export const updatingMiddleware = if (initExisting.match(action) || initEmpty.match(action)) { return; } - updater(datasourceStates[activeDatasourceId].state, visualization.state); + + updater( + datasourceStates[activeDatasourceId].state, + visualization.state, + visualization.activeId + ); } }; @@ -88,6 +102,7 @@ export async function getEditLensConfiguration( return ({ attributes, updatePanelState, + updateSuggestion, closeFlyout, wrapInFlyout, datasourceId, @@ -98,10 +113,13 @@ export async function getEditLensConfiguration( updateByRefInput, navigateToLensEditor, displayFlyoutHeader, + canEditTextBasedQuery, }: EditLensConfigurationProps) => { if (!lensServices || !datasourceMap || !visualizationMap) { return ; } + const [currentAttributes, setCurrentAttributes] = + useState(attributes); /** * During inline editing of a by reference panel, the panel is converted to a by value one. * When the user applies the changes we save them to the Lens SO @@ -117,7 +135,7 @@ export async function getEditLensConfiguration( }, [savedObjectId] ); - const datasourceState = attributes.state.datasourceStates[datasourceId]; + const datasourceState = currentAttributes.state.datasourceStates[datasourceId]; const storeDeps = { lensServices, datasourceMap, @@ -135,7 +153,7 @@ export async function getEditLensConfiguration( lensStore.dispatch( loadInitial({ initialInput: { - attributes, + attributes: currentAttributes, id: panelId ?? generateId(), }, inlineEditing: true, @@ -148,6 +166,7 @@ export async function getEditLensConfiguration( { closeFlyout?.(); }} @@ -169,8 +188,9 @@ export async function getEditLensConfiguration( }; const configPanelProps = { - attributes, + attributes: currentAttributes, updatePanelState, + updateSuggestion, closeFlyout, datasourceId, coreStart, @@ -184,6 +204,8 @@ export async function getEditLensConfiguration( updateByRefInput, navigateToLensEditor, displayFlyoutHeader, + canEditTextBasedQuery, + setCurrentAttributes, }; return getWrapper( diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts new file mode 100644 index 000000000000..0fe5f148a25d --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts @@ -0,0 +1,127 @@ +/* + * 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 { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import { createMockStartDependencies } from '../../../editor_frame_service/mocks'; +import { + mockVisualizationMap, + mockDatasourceMap, + mockDataViewWithTimefield, + mockAllSuggestions, +} from '../../../mocks'; +import { suggestionsApi } from '../../../lens_suggestions_api'; +import { fetchDataFromAggregateQuery } from '../../../datasources/text_based/fetch_data_from_aggregate_query'; +import { getSuggestions } from './helpers'; + +const mockSuggestionApi = suggestionsApi as jest.Mock; +const mockFetchData = fetchDataFromAggregateQuery as jest.Mock; + +jest.mock('../../../lens_suggestions_api', () => ({ + suggestionsApi: jest.fn(() => mockAllSuggestions), +})); + +jest.mock('../../../datasources/text_based/fetch_data_from_aggregate_query', () => ({ + fetchDataFromAggregateQuery: jest.fn(() => { + return { + columns: [ + { + name: '@timestamp', + id: '@timestamp', + meta: { + type: 'date', + }, + }, + { + name: 'bytes', + id: 'bytes', + meta: { + type: 'number', + }, + }, + { + name: 'memory', + id: 'memory', + meta: { + type: 'number', + }, + }, + ], + }; + }), +})); + +describe('getSuggestions', () => { + const query = { + esql: 'from index1 | limit 10 | stats average = avg(bytes', + }; + const mockStartDependencies = + createMockStartDependencies() as unknown as LensPluginStartDependencies; + const dataViews = dataViewPluginMocks.createStartContract(); + dataViews.create.mockResolvedValue(mockDataViewWithTimefield); + const dataviewSpecArr = [ + { + id: 'd2588ae7-9ea0-4439-9f5b-f808754a3b97', + title: 'index1', + timeFieldName: '@timestamp', + sourceFilters: [], + fieldFormats: {}, + runtimeFieldMap: {}, + fieldAttrs: {}, + allowNoIndex: false, + name: 'index1', + }, + ]; + const startDependencies = { + ...mockStartDependencies, + dataViews, + }; + + it('returns the suggestions attributes correctly', async () => { + const suggestionsAttributes = await getSuggestions( + query, + startDependencies, + mockDatasourceMap(), + mockVisualizationMap(), + dataviewSpecArr, + jest.fn() + ); + expect(suggestionsAttributes?.visualizationType).toBe(mockAllSuggestions[0].visualizationId); + expect(suggestionsAttributes?.state.visualization).toStrictEqual( + mockAllSuggestions[0].visualizationState + ); + }); + + it('returns undefined if no suggestions are computed', async () => { + mockSuggestionApi.mockResolvedValueOnce([]); + const suggestionsAttributes = await getSuggestions( + query, + startDependencies, + mockDatasourceMap(), + mockVisualizationMap(), + dataviewSpecArr, + jest.fn() + ); + expect(suggestionsAttributes).toBeUndefined(); + }); + + it('returns an error if fetching the data fails', async () => { + mockFetchData.mockImplementation(() => { + throw new Error('sorry!'); + }); + const setErrorsSpy = jest.fn(); + const suggestionsAttributes = await getSuggestions( + query, + startDependencies, + mockDatasourceMap(), + mockVisualizationMap(), + dataviewSpecArr, + setErrorsSpy + ); + expect(suggestionsAttributes).toBeUndefined(); + expect(setErrorsSpy).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts new file mode 100644 index 000000000000..faecb37ba7fd --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts @@ -0,0 +1,148 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { i18n } from '@kbn/i18n'; +import { getIndexPatternFromSQLQuery, getIndexPatternFromESQLQuery } from '@kbn/es-query'; +import type { AggregateQuery, Query, Filter } from '@kbn/es-query'; +import type { DataView, DataViewSpec } from '@kbn/data-views-plugin/public'; +import type { Suggestion } from '../../../types'; +import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import type { DatasourceMap, VisualizationMap } from '../../../types'; +import { fetchDataFromAggregateQuery } from '../../../datasources/text_based/fetch_data_from_aggregate_query'; +import { suggestionsApi } from '../../../lens_suggestions_api'; + +export const getQueryColumns = async ( + query: AggregateQuery, + dataView: DataView, + deps: LensPluginStartDependencies +) => { + // Fetching only columns for ES|QL for performance reasons with limit 0 + // Important note: ES doesnt return the warnings for 0 limit, + // I am skipping them in favor of performance now + // but we should think another way to get them (from Lens embeddable or store) + const performantQuery = { ...query }; + if ('esql' in performantQuery && performantQuery.esql) { + performantQuery.esql = `${performantQuery.esql} | limit 0`; + } + const table = await fetchDataFromAggregateQuery( + performantQuery, + dataView, + deps.data, + deps.expressions + ); + return table?.columns; +}; + +export const getSuggestions = async ( + query: AggregateQuery, + deps: LensPluginStartDependencies, + datasourceMap: DatasourceMap, + visualizationMap: VisualizationMap, + adHocDataViews: DataViewSpec[], + setErrors: (errors: Error[]) => void +) => { + try { + let indexPattern = ''; + if ('sql' in query) { + indexPattern = getIndexPatternFromSQLQuery(query.sql); + } + if ('esql' in query) { + indexPattern = getIndexPatternFromESQLQuery(query.esql); + } + const dataViewSpec = adHocDataViews.find((adHoc) => { + return adHoc.name === indexPattern; + }); + + const dataView = await deps.dataViews.create( + dataViewSpec ?? { + title: indexPattern, + } + ); + if (dataView.fields.getByName('@timestamp')?.type === 'date' && !dataViewSpec) { + dataView.timeFieldName = '@timestamp'; + } + const columns = await getQueryColumns(query, dataView, deps); + const context = { + dataViewSpec: dataView?.toSpec(), + fieldName: '', + textBasedColumns: columns, + query, + }; + + const allSuggestions = + suggestionsApi({ context, dataView, datasourceMap, visualizationMap }) ?? []; + + // Lens might not return suggestions for some cases, i.e. in case of errors + if (!allSuggestions.length) return undefined; + + const firstSuggestion = allSuggestions[0]; + + const attrs = getLensAttributes({ + filters: [], + query, + suggestion: firstSuggestion, + dataView, + }); + return attrs; + } catch (e) { + setErrors([e]); + } + return undefined; +}; + +export const getLensAttributes = ({ + filters, + query, + suggestion, + dataView, +}: { + filters: Filter[]; + query: Query | AggregateQuery; + suggestion: Suggestion | undefined; + dataView?: DataView; +}) => { + const suggestionDatasourceState = Object.assign({}, suggestion?.datasourceState); + const suggestionVisualizationState = Object.assign({}, suggestion?.visualizationState); + const datasourceStates = + suggestion && suggestion.datasourceState + ? { + [suggestion.datasourceId!]: { + ...suggestionDatasourceState, + }, + } + : { + formBased: {}, + }; + const visualization = suggestionVisualizationState; + const attributes = { + title: suggestion + ? suggestion.title + : i18n.translate('xpack.lens.config.suggestion.title', { + defaultMessage: 'New suggestion', + }), + references: [ + { + id: dataView?.id ?? '', + name: `textBasedLanguages-datasource-layer-suggestion`, + type: 'index-pattern', + }, + ], + state: { + datasourceStates, + filters, + query, + visualization, + ...(dataView && + dataView.id && + !dataView.isPersisted() && { + adHocDataViews: { [dataView.id]: dataView.toSpec(false) }, + }), + }, + visualizationType: suggestion ? suggestion.visualizationId : 'lnsXY', + } as TypedLensByValueInput['attributes']; + return attributes; +}; diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/layer_configuration_section.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/layer_configuration_section.tsx new file mode 100644 index 000000000000..7ae7b456ab66 --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/layer_configuration_section.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useMemo } from 'react'; +import { EuiSpacer, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; +import { VisualizationToolbar } from '../../../editor_frame_service/editor_frame/workspace_panel'; +import { ConfigPanelWrapper } from '../../../editor_frame_service/editor_frame/config_panel/config_panel'; +import { createIndexPatternService } from '../../../data_views_service/service'; +import { useLensDispatch, updateIndexPatterns } from '../../../state_management'; +import { replaceIndexpattern } from '../../../state_management/lens_slice'; +import type { LayerConfigurationProps } from './types'; +import { useLensSelector } from '../../../state_management'; + +export function LayerConfiguration({ + attributes, + coreStart, + startDependencies, + visualizationMap, + datasourceMap, + datasourceId, + framePublicAPI, + hasPadding, + setIsInlineFlyoutVisible, +}: LayerConfigurationProps) { + const dispatch = useLensDispatch(); + const { euiTheme } = useEuiTheme(); + const { visualization } = useLensSelector((state) => state.lens); + const activeVisualization = + visualizationMap[visualization.activeId ?? attributes.visualizationType]; + const indexPatternService = useMemo( + () => + createIndexPatternService({ + dataViews: startDependencies.dataViews, + uiActions: startDependencies.uiActions, + core: coreStart, + updateIndexPatterns: (newIndexPatternsState, options) => { + dispatch(updateIndexPatterns(newIndexPatternsState)); + }, + replaceIndexPattern: (newIndexPattern, oldId, options) => { + dispatch(replaceIndexpattern({ newIndexPattern, oldId })); + }, + }), + [coreStart, dispatch, startDependencies.dataViews, startDependencies.uiActions] + ); + + const layerPanelsProps = { + framePublicAPI, + datasourceMap, + visualizationMap, + core: coreStart, + dataViews: startDependencies.dataViews, + uiActions: startDependencies.uiActions, + hideLayerHeader: datasourceId === 'textBased', + indexPatternService, + setIsInlineFlyoutVisible, + }; + return ( +
    + + + +
    + ); +} diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx index 4731afe03724..0462e4ad251d 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.test.tsx @@ -14,10 +14,8 @@ import { mockVisualizationMap, mockDatasourceMap, mockDataPlugin } from '../../. import type { LensPluginStartDependencies } from '../../../plugin'; import { createMockStartDependencies } from '../../../editor_frame_service/mocks'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; -import { - LensEditConfigurationFlyout, - type EditConfigPanelProps, -} from './lens_configuration_flyout'; +import { LensEditConfigurationFlyout } from './lens_configuration_flyout'; +import type { EditConfigPanelProps } from './types'; const lensAttributes = { title: 'test', @@ -29,14 +27,12 @@ const lensAttributes = { visualization: {}, filters: [], query: { - language: 'lucene', - query: '', + esql: 'from index1 | limit 10', }, }, filters: [], query: { - language: 'lucene', - query: '', + esql: 'from index1 | limit 10', }, references: [], } as unknown as TypedLensByValueInput['attributes']; @@ -109,6 +105,16 @@ describe('LensEditConfigurationFlyout', () => { expect(closeFlyoutSpy).toHaveBeenCalled(); }); + it('should call the updatePanelState callback if cancel button is clicked', async () => { + const updatePanelStateSpy = jest.fn(); + renderConfigFlyout({ + updatePanelState: updatePanelStateSpy, + }); + expect(screen.getByTestId('lns-layerPanel-0')).toBeInTheDocument(); + userEvent.click(screen.getByTestId('cancelFlyoutButton')); + expect(updatePanelStateSpy).toHaveBeenCalled(); + }); + it('should call the updateByRefInput callback if cancel button is clicked and savedObjectId exists', async () => { const updateByRefInputSpy = jest.fn(); @@ -135,4 +141,41 @@ describe('LensEditConfigurationFlyout', () => { expect(updateByRefInputSpy).toHaveBeenCalled(); expect(saveByRefSpy).toHaveBeenCalled(); }); + + it('should not display the editor if canEditTextBasedQuery prop is false', async () => { + renderConfigFlyout({ + canEditTextBasedQuery: false, + }); + expect(screen.queryByTestId('TextBasedLangEditor')).toBeNull(); + }); + + it('should not display the editor if canEditTextBasedQuery prop is true but the query is not text based', async () => { + renderConfigFlyout({ + canEditTextBasedQuery: true, + attributes: { + ...lensAttributes, + state: { + ...lensAttributes.state, + query: { + type: 'kql', + query: '', + } as unknown as Query, + }, + }, + }); + expect(screen.queryByTestId('TextBasedLangEditor')).toBeNull(); + }); + + it('should display the suggestions if canEditTextBasedQuery prop is true', async () => { + renderConfigFlyout( + { + canEditTextBasedQuery: true, + }, + { + esql: 'from index1 | limit 10', + } + ); + expect(screen.getByTestId('InlineEditingESQLEditor')).toBeInTheDocument(); + expect(screen.getByTestId('InlineEditingSuggestions')).toBeInTheDocument(); + }); }); diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index a60e3df063aa..72dbd313d645 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -6,85 +6,34 @@ */ import React, { useMemo, useCallback, useRef, useEffect, useState } from 'react'; +import { isEqual } from 'lodash'; +import { css } from '@emotion/react'; +import { i18n } from '@kbn/i18n'; import { - EuiButtonEmpty, - EuiButton, - EuiFlyoutBody, - EuiFlyoutFooter, EuiTitle, - EuiLink, - EuiIcon, - EuiToolTip, - EuiSpacer, + EuiAccordion, + useEuiTheme, EuiFlexGroup, EuiFlexItem, - useEuiTheme, - EuiCallOut, + euiScrollBarStyles, } from '@elastic/eui'; -import { isEqual } from 'lodash'; -import type { Observable } from 'rxjs'; import { euiThemeVars } from '@kbn/ui-theme'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { css } from '@emotion/react'; -import type { CoreStart } from '@kbn/core/public'; import type { Datatable } from '@kbn/expressions-plugin/public'; -import type { LensPluginStartDependencies } from '../../../plugin'; import { - useLensSelector, - selectFramePublicAPI, - useLensDispatch, - updateIndexPatterns, -} from '../../../state_management'; -import { replaceIndexpattern } from '../../../state_management/lens_slice'; -import { VisualizationToolbar } from '../../../editor_frame_service/editor_frame/workspace_panel'; - -import type { DatasourceMap, VisualizationMap } from '../../../types'; + getAggregateQueryMode, + isOfAggregateQueryType, + getLanguageDisplayName, +} from '@kbn/es-query'; +import type { AggregateQuery, Query } from '@kbn/es-query'; +import { TextBasedLangEditor } from '@kbn/text-based-languages/public'; +import { useLensSelector, selectFramePublicAPI } from '../../../state_management'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; -import type { LensEmbeddableOutput } from '../../../embeddable'; -import type { LensInspector } from '../../../lens_inspector_service'; -import { ConfigPanelWrapper } from '../../../editor_frame_service/editor_frame/config_panel/config_panel'; import { extractReferencesFromState } from '../../../utils'; -import type { Document } from '../../../persistence'; -import { createIndexPatternService } from '../../../data_views_service/service'; - -export interface EditConfigPanelProps { - coreStart: CoreStart; - startDependencies: LensPluginStartDependencies; - visualizationMap: VisualizationMap; - datasourceMap: DatasourceMap; - /** The attributes of the Lens embeddable */ - attributes: TypedLensByValueInput['attributes']; - /** Callback for updating the visualization and datasources state */ - updatePanelState: (datasourceState: unknown, visualizationState: unknown) => void; - /** Lens visualizations can be either created from ESQL (textBased) or from dataviews (formBased) */ - datasourceId: 'formBased' | 'textBased'; - /** Embeddable output observable, useful for dashboard flyout */ - output$?: Observable; - /** Contains the active data, necessary for some panel configuration such as coloring */ - lensAdapters?: LensInspector['adapters']; - /** Optional callback called when updating the by reference embeddable */ - updateByRefInput?: (soId: string) => void; - /** Callback for closing the edit flyout */ - closeFlyout?: () => void; - /** Boolean used for adding a flyout wrapper */ - wrapInFlyout?: boolean; - /** Optional parameter for panel identification - * If not given, Lens generates a new one - */ - panelId?: string; - /** Optional parameter for saved object id - * Should be given if the lens embeddable is a by reference one - * (saved in the library) - */ - savedObjectId?: string; - /** Callback for saving the embeddable as a SO */ - saveByRef?: (attrs: Document) => void; - /** Optional callback for navigation from the header of the flyout */ - navigateToLensEditor?: () => void; - /** If set to true it displays a header on the flyout */ - displayFlyoutHeader?: boolean; -} +import { LayerConfiguration } from './layer_configuration_section'; +import type { EditConfigPanelProps } from './types'; +import { FlyoutWrapper } from './flyout_wrapper'; +import { getSuggestions } from './helpers'; +import { SuggestionPanel } from '../../../editor_frame_service/editor_frame/suggestion_panel'; export function LensEditConfigurationFlyout({ attributes, @@ -94,6 +43,8 @@ export function LensEditConfigurationFlyout({ datasourceMap, datasourceId, updatePanelState, + updateSuggestion, + setCurrentAttributes, closeFlyout, saveByRef, savedObjectId, @@ -102,15 +53,21 @@ export function LensEditConfigurationFlyout({ lensAdapters, navigateToLensEditor, displayFlyoutHeader, + canEditTextBasedQuery, }: EditConfigPanelProps) { + const euiTheme = useEuiTheme(); const previousAttributes = useRef(attributes); + const prevQuery = useRef(attributes.state.query); + const [query, setQuery] = useState(attributes.state.query); + const [errors, setErrors] = useState(); + const [isInlineFlyoutVisible, setIsInlineFlyoutVisible] = useState(true); + const [isLayerAccordionOpen, setIsLayerAccordionOpen] = useState(true); + const [isSuggestionsAccordionOpen, setIsSuggestionsAccordionOpen] = useState(false); const datasourceState = attributes.state.datasourceStates[datasourceId]; const activeVisualization = visualizationMap[attributes.visualizationType]; const activeDatasource = datasourceMap[datasourceId]; - const [isInlineFooterVisible, setIsInlineFlyoutFooterVisible] = useState(true); - const { euiTheme } = useEuiTheme(); const { datasourceStates, visualization, isLoading } = useLensSelector((state) => state.lens); - const dispatch = useLensDispatch(); + const suggestsLimitedColumns = activeDatasource?.suggestsLimitedColumns?.(datasourceState); const activeData: Record = useMemo(() => { return {}; }, []); @@ -149,28 +106,34 @@ export function LensEditConfigurationFlyout({ const onCancel = useCallback(() => { const previousAttrs = previousAttributes.current; - if (attributesChanged) { - const currentDatasourceState = datasourceMap[datasourceId].injectReferencesToLayers - ? datasourceMap[datasourceId]?.injectReferencesToLayers?.( - previousAttrs.state.datasourceStates[datasourceId], - previousAttrs.references - ) - : previousAttrs.state.datasourceStates[datasourceId]; - updatePanelState?.(currentDatasourceState, previousAttrs.state.visualization); + if (previousAttrs.visualizationType === visualization.activeId) { + const currentDatasourceState = datasourceMap[datasourceId].injectReferencesToLayers + ? datasourceMap[datasourceId]?.injectReferencesToLayers?.( + previousAttrs.state.datasourceStates[datasourceId], + previousAttrs.references + ) + : previousAttrs.state.datasourceStates[datasourceId]; + updatePanelState?.(currentDatasourceState, previousAttrs.state.visualization); + } else { + updateSuggestion?.(previousAttrs); + } if (savedObjectId) { updateByRefInput?.(savedObjectId); } } closeFlyout?.(); }, [ + previousAttributes, attributesChanged, - savedObjectId, closeFlyout, datasourceMap, datasourceId, updatePanelState, + updateSuggestion, + savedObjectId, updateByRefInput, + visualization, ]); const onApply = useCallback(() => { @@ -218,20 +181,33 @@ export function LensEditConfigurationFlyout({ datasourceMap, ]); - const indexPatternService = useMemo( - () => - createIndexPatternService({ - dataViews: startDependencies.dataViews, - uiActions: startDependencies.uiActions, - core: coreStart, - updateIndexPatterns: (newIndexPatternsState, options) => { - dispatch(updateIndexPatterns(newIndexPatternsState)); - }, - replaceIndexPattern: (newIndexPattern, oldId, options) => { - dispatch(replaceIndexpattern({ newIndexPattern, oldId })); - }, - }), - [coreStart, dispatch, startDependencies.dataViews, startDependencies.uiActions] + // needed for text based languages mode which works ONLY with adHoc dataviews + const adHocDataViews = Object.values(attributes.state.adHocDataViews ?? {}); + + const runQuery = useCallback( + async (q) => { + const attrs = await getSuggestions( + q, + startDependencies, + datasourceMap, + visualizationMap, + adHocDataViews, + setErrors + ); + if (attrs) { + setCurrentAttributes?.(attrs); + setErrors([]); + updateSuggestion?.(attrs); + } + }, + [ + startDependencies, + datasourceMap, + visualizationMap, + adHocDataViews, + setCurrentAttributes, + updateSuggestion, + ] ); const framePublicAPI = useLensSelector((state) => { @@ -244,155 +220,197 @@ export function LensEditConfigurationFlyout({ }; return selectFramePublicAPI(newState, datasourceMap); }); + + const textBasedMode = isOfAggregateQueryType(query) ? getAggregateQueryMode(query) : undefined; + if (isLoading) return null; + // Example is the Discover editing where we dont want to render the text based editor on the panel + if (!canEditTextBasedQuery) { + return ( + + + + ); + } - const layerPanelsProps = { - framePublicAPI, - datasourceMap, - visualizationMap, - core: coreStart, - dataViews: startDependencies.dataViews, - uiActions: startDependencies.uiActions, - hideLayerHeader: datasourceId === 'textBased', - indexPatternService, - setIsInlineFlyoutFooterVisible, - }; return ( <> - * { - pointer-events: auto; - } - } - .euiFlyoutBody__overflowContent { - padding: 0; - } - `} + - - {displayFlyoutHeader && ( - - - - - - -

    - {i18n.translate('xpack.lens.config.editVisualizationLabel', { - defaultMessage: 'Edit visualization', - })} -

    -
    -
    - - - - - -
    -
    - {navigateToLensEditor && ( - - - {i18n.translate('xpack.lens.config.editLinkLabel', { - defaultMessage: 'Edit in Lens', - })} - - - )} -
    + + {isOfAggregateQueryType(query) && ( + + { + setQuery(q); + prevQuery.current = q; + }} + expandCodeEditor={(status: boolean) => {}} + isCodeEditorExpanded + detectTimestamp={Boolean(adHocDataViews?.[0]?.timeFieldName)} + errors={errors} + warning={ + suggestsLimitedColumns + ? i18n.translate('xpack.lens.config.configFlyoutCallout', { + defaultMessage: + 'Displaying a limited portion of the available fields. Add more from the configuration panel.', + }) + : undefined + } + hideMinimizeButton + editorIsInline + hideRunQueryText + disableSubmitAction={isEqual(query, prevQuery.current)} + onTextLangQuerySubmit={(q) => { + if (q) { + runQuery(q); + } + }} + isDisabled={false} + /> )} - {datasourceId === 'textBased' && ( - +
    + {i18n.translate('xpack.lens.config.layerConfigurationLabel', { + defaultMessage: 'Layer configuration', + })} +
    + + } + buttonProps={{ + paddingSize: 'm', + }} + initialIsOpen={isLayerAccordionOpen} + forceState={isLayerAccordionOpen ? 'open' : 'closed'} + onToggle={(status) => { + if (status && isSuggestionsAccordionOpen) { + setIsSuggestionsAccordionOpen(!status); + } + setIsLayerAccordionOpen(!isLayerAccordionOpen); + }} + > + - )} - - - - +
    + + + { + if (!status && isLayerAccordionOpen) { + setIsLayerAccordionOpen(status); + } + setIsSuggestionsAccordionOpen(!isSuggestionsAccordionOpen); + }} />
    -
    - {isInlineFooterVisible && ( - - - - - - - - - - - - - - - )} + ); } diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/types.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/types.ts new file mode 100644 index 000000000000..ae207865bbf9 --- /dev/null +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/types.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { Observable } from 'rxjs'; +import type { CoreStart } from '@kbn/core/public'; +import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; +import type { LensPluginStartDependencies } from '../../../plugin'; +import type { DatasourceMap, VisualizationMap, FramePublicAPI } from '../../../types'; +import type { LensEmbeddableOutput } from '../../../embeddable'; +import type { LensInspector } from '../../../lens_inspector_service'; +import type { Document } from '../../../persistence'; + +export interface FlyoutWrapperProps { + children: JSX.Element; + isInlineFlyoutVisible: boolean; + isScrollable: boolean; + displayFlyoutHeader?: boolean; + language?: string; + attributesChanged?: boolean; + onCancel?: () => void; + onApply?: () => void; + navigateToLensEditor?: () => void; +} + +export interface EditConfigPanelProps { + coreStart: CoreStart; + startDependencies: LensPluginStartDependencies; + visualizationMap: VisualizationMap; + datasourceMap: DatasourceMap; + /** The attributes of the Lens embeddable */ + attributes: TypedLensByValueInput['attributes']; + /** Callback for updating the visualization and datasources state.*/ + updatePanelState: ( + datasourceState: unknown, + visualizationState: unknown, + visualizationType?: string + ) => void; + updateSuggestion?: (attrs: TypedLensByValueInput['attributes']) => void; + /** Set the attributes state */ + setCurrentAttributes?: (attrs: TypedLensByValueInput['attributes']) => void; + /** Lens visualizations can be either created from ESQL (textBased) or from dataviews (formBased) */ + datasourceId: 'formBased' | 'textBased'; + /** Embeddable output observable, useful for dashboard flyout */ + output$?: Observable; + /** Contains the active data, necessary for some panel configuration such as coloring */ + lensAdapters?: LensInspector['adapters']; + /** Optional callback called when updating the by reference embeddable */ + updateByRefInput?: (soId: string) => void; + /** Callback for closing the edit flyout */ + closeFlyout?: () => void; + /** Boolean used for adding a flyout wrapper */ + wrapInFlyout?: boolean; + /** Optional parameter for panel identification + * If not given, Lens generates a new one + */ + panelId?: string; + /** Optional parameter for saved object id + * Should be given if the lens embeddable is a by reference one + * (saved in the library) + */ + savedObjectId?: string; + /** Callback for saving the embeddable as a SO */ + saveByRef?: (attrs: Document) => void; + /** Optional callback for navigation from the header of the flyout */ + navigateToLensEditor?: () => void; + /** If set to true it displays a header on the flyout */ + displayFlyoutHeader?: boolean; + /** If set to true the layout changes to accordion and the text based query (i.e. ES|QL) can be edited */ + canEditTextBasedQuery?: boolean; +} + +export interface LayerConfigurationProps { + attributes: TypedLensByValueInput['attributes']; + coreStart: CoreStart; + startDependencies: LensPluginStartDependencies; + visualizationMap: VisualizationMap; + datasourceMap: DatasourceMap; + datasourceId: 'formBased' | 'textBased'; + framePublicAPI: FramePublicAPI; + hasPadding?: boolean; + setIsInlineFlyoutVisible: (flag: boolean) => void; +} diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx index ef4811f254cb..ca9d48c17cbb 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx @@ -13,6 +13,7 @@ import { column3, numericDraggedColumn, fieldList, + fieldListNonNumericOnly, notNumericDraggedField, numericDraggedField, } from './mocks'; @@ -74,6 +75,23 @@ describe('Text-based: getDropProps', () => { } as unknown as DatasourceDimensionDropHandlerProps; expect(getDropProps(props)).toBeUndefined(); }); + it('should not return undefined if source is a non-numeric field, target is a metric dimension but datatable doesnt have numeric fields', () => { + const props = { + ...defaultProps, + state: { + ...defaultProps.state, + layers: { + first: { + columns: [column1, column2, column3], + allColumns: [...fieldListNonNumericOnly, column1, column2, column3], + }, + }, + fieldList: fieldListNonNumericOnly, + }, + source: notNumericDraggedField, + } as unknown as DatasourceDimensionDropHandlerProps; + expect(getDropProps(props)).toEqual({ dropTypes: ['field_replace'], nextLabel: 'category' }); + }); it('should return reorder if source and target are operations from the same group', () => { const props = { ...defaultProps, diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx index 9f79fff3d608..78e1c98f3a30 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx @@ -10,6 +10,7 @@ import { isOperation } from '../../../types'; import type { TextBasedPrivateState } from '../types'; import type { GetDropPropsArgs } from '../../../types'; import { isDraggedField, isOperationFromTheSameGroup } from '../../../utils'; +import { canColumnBeDroppedInMetricDimension } from '../utils'; export const getDropProps = ( props: GetDropPropsArgs @@ -44,14 +45,24 @@ export const getDropProps = ( return { dropTypes: ['reorder'], nextLabel }; } + const sourceFieldCanMoveToMetricDimension = canColumnBeDroppedInMetricDimension( + layer.allColumns, + sourceField?.meta?.type + ); + + const targetFieldCanMoveToMetricDimension = canColumnBeDroppedInMetricDimension( + layer.allColumns, + targetField?.meta?.type + ); + const isMoveable = !target?.isMetricDimension || - (target.isMetricDimension && sourceField?.meta?.type === 'number'); + (target.isMetricDimension && sourceFieldCanMoveToMetricDimension); if (targetColumn) { const isSwappable = (isMoveable && !source?.isMetricDimension) || - (source.isMetricDimension && targetField?.meta?.type === 'number'); + (source.isMetricDimension && targetFieldCanMoveToMetricDimension); if (isMoveable) { if (isSwappable) { return { diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx index 5cb3bcd37e2c..90a37acab104 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx @@ -83,6 +83,37 @@ export const numericDraggedField = { }, }; +export const fieldListNonNumericOnly = [ + { + columnId: 'category', + fieldName: 'category', + meta: { + type: 'string', + }, + }, + { + columnId: 'currency', + fieldName: 'currency', + meta: { + type: 'string', + }, + }, + { + columnId: 'products.sold_date', + fieldName: 'products.sold_date', + meta: { + type: 'date', + }, + }, + { + columnId: 'products.buyer', + fieldName: 'products.buyer', + meta: { + type: 'string', + }, + }, +]; + export const fieldList = [ { columnId: 'category', diff --git a/x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx deleted file mode 100644 index d6e4be8c9938..000000000000 --- a/x-pack/plugins/lens/public/datasources/text_based/layerpanel.test.tsx +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import type { DatatableColumn } from '@kbn/expressions-plugin/public'; -import { TextBasedPrivateState } from './types'; -import type { DataViewsState } from '../../state_management/types'; - -import { TextBasedLayerPanelProps, LayerPanel } from './layerpanel'; -import { shallowWithIntl as shallow } from '@kbn/test-jest-helpers'; -import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; - -const fields = [ - { - name: 'timestamp', - id: 'timestamp', - meta: { - type: 'date', - }, - }, - { - name: 'bytes', - id: 'bytes', - meta: { - type: 'number', - }, - }, - { - name: 'memory', - id: 'memory', - meta: { - type: 'number', - }, - }, -] as DatatableColumn[]; - -const initialState: TextBasedPrivateState = { - layers: { - first: { - index: '1', - columns: [], - allColumns: [], - query: { sql: 'SELECT * FROM foo' }, - }, - }, - indexPatternRefs: [ - { id: '1', title: 'my-fake-index-pattern' }, - { id: '2', title: 'my-fake-restricted-pattern' }, - { id: '3', title: 'my-compatible-pattern' }, - ], - fieldList: fields, -}; -describe('Layer Data Panel', () => { - let defaultProps: TextBasedLayerPanelProps; - - beforeEach(() => { - defaultProps = { - layerId: 'first', - state: initialState, - onChangeIndexPattern: jest.fn(), - dataViews: { - indexPatternRefs: [ - { id: '1', title: 'my-fake-index-pattern', name: 'My fake index pattern' }, - { id: '2', title: 'my-fake-restricted-pattern', name: 'my-fake-restricted-pattern' }, - { id: '3', title: 'my-compatible-pattern', name: 'my-compatible-pattern' }, - ], - indexPatterns: {}, - } as DataViewsState, - }; - }); - - it('should display the selected dataview but disabled', () => { - const instance = shallow(); - expect(instance.find(ChangeIndexPattern).prop('trigger')).toStrictEqual({ - fontWeight: 'normal', - isDisabled: true, - label: 'my-fake-index-pattern', - size: 's', - title: 'my-fake-index-pattern', - }); - }); -}); diff --git a/x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx deleted file mode 100644 index 3ce8c333114f..000000000000 --- a/x-pack/plugins/lens/public/datasources/text_based/layerpanel.tsx +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { i18n } from '@kbn/i18n'; -import { DatasourceLayerPanelProps } from '../../types'; -import { TextBasedPrivateState } from './types'; -import { ChangeIndexPattern } from '../../shared_components/dataview_picker/dataview_picker'; - -export interface TextBasedLayerPanelProps extends DatasourceLayerPanelProps { - state: TextBasedPrivateState; -} - -export function LayerPanel({ state, layerId, dataViews }: TextBasedLayerPanelProps) { - const layer = state.layers[layerId]; - const dataView = state.indexPatternRefs.find((ref) => ref.id === layer.index); - - const notFoundTitleLabel = i18n.translate('xpack.lens.layerPanel.missingDataView', { - defaultMessage: 'Data view not found', - }); - return ( - {}} - /> - ); -} diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts index 8aab2f367095..1528a3ff623c 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts @@ -116,7 +116,7 @@ describe('Textbased Data Source', () => { }, ], index: 'foo', - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, }, }, fieldList: [ @@ -226,7 +226,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: 'foo', }, }, @@ -261,7 +261,7 @@ describe('Textbased Data Source', () => { ...baseState.layers, newLayer: { index: 'foo', - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, allColumns: [ { columnId: 'col1', @@ -296,7 +296,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: 'foo', }, }, @@ -353,7 +353,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: 'foo', }, }, @@ -402,12 +402,20 @@ describe('Textbased Data Source', () => { expect(suggestions[0].state).toEqual({ ...state, fieldList: textBasedQueryColumns, + indexPatternRefs: [ + { + id: '1', + timeField: undefined, + title: 'foo', + }, + ], layers: { newid: { allColumns: [ { columnId: 'bytes', fieldName: 'bytes', + inMetricDimension: true, meta: { type: 'number', }, @@ -424,6 +432,7 @@ describe('Textbased Data Source', () => { { columnId: 'bytes', fieldName: 'bytes', + inMetricDimension: true, meta: { type: 'number', }, @@ -466,6 +475,7 @@ describe('Textbased Data Source', () => { ], isMultiRow: false, layerId: 'newid', + notAssignedMetrics: false, }); }); @@ -504,6 +514,175 @@ describe('Textbased Data Source', () => { ); expect(suggestions).toEqual([]); }); + + it('should return the correct suggestions if non numeric columns are given', () => { + const textBasedQueryColumns = [ + { + id: '@timestamp', + name: '@timestamp', + meta: { + type: 'date', + }, + }, + { + id: 'dest', + name: 'dest', + meta: { + type: 'string', + }, + }, + ]; + const state = { + layers: {}, + initialContext: { + textBasedColumns: textBasedQueryColumns, + query: { esql: 'from foo' }, + dataViewSpec: { + title: 'foo', + id: '1', + name: 'Foo', + }, + }, + } as unknown as TextBasedPrivateState; + const suggestions = TextBasedDatasource.getDatasourceSuggestionsForVisualizeField( + state, + '1', + '', + indexPatterns + ); + expect(suggestions[0].state).toEqual({ + ...state, + fieldList: textBasedQueryColumns, + indexPatternRefs: [ + { + id: '1', + timeField: undefined, + title: 'foo', + }, + ], + layers: { + newid: { + allColumns: [ + { + columnId: '@timestamp', + fieldName: '@timestamp', + inMetricDimension: true, + meta: { + type: 'date', + }, + }, + { + columnId: 'dest', + fieldName: 'dest', + inMetricDimension: true, + meta: { + type: 'string', + }, + }, + ], + columns: [ + { + columnId: '@timestamp', + fieldName: '@timestamp', + inMetricDimension: true, + meta: { + type: 'date', + }, + }, + { + columnId: 'dest', + fieldName: 'dest', + inMetricDimension: true, + meta: { + type: 'string', + }, + }, + ], + index: '1', + query: { + esql: 'from foo', + }, + }, + }, + }); + + expect(suggestions[0].table).toEqual({ + changeType: 'initial', + columns: [ + { + columnId: '@timestamp', + operation: { + dataType: 'date', + isBucketed: true, + label: '@timestamp', + }, + }, + { + columnId: 'dest', + operation: { + dataType: 'string', + isBucketed: true, + label: 'dest', + }, + }, + ], + isMultiRow: false, + layerId: 'newid', + notAssignedMetrics: true, + }); + }); + }); + + describe('#suggestsLimitedColumns', () => { + it('should return true if query returns big number of columns', () => { + const fieldList = [ + { + id: 'a', + name: 'Test 1', + meta: { + type: 'number', + }, + }, + { + id: 'b', + name: 'Test 2', + meta: { + type: 'number', + }, + }, + { + id: 'c', + name: 'Test 3', + meta: { + type: 'date', + }, + }, + { + id: 'd', + name: 'Test 4', + meta: { + type: 'string', + }, + }, + { + id: 'e', + name: 'Test 5', + meta: { + type: 'string', + }, + }, + ]; + const state = { + fieldList, + layers: { + a: { + query: { esql: 'from foo' }, + index: 'foo', + }, + }, + } as unknown as TextBasedPrivateState; + expect(TextBasedDatasource?.suggestsLimitedColumns?.(state)).toBeTruthy(); + }); }); describe('#getUserMessages', () => { @@ -544,7 +723,7 @@ describe('Textbased Data Source', () => { }, ], errors: [new Error('error 1'), new Error('error 2')], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: 'foo', }, }, @@ -626,7 +805,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: '1', }, }, @@ -673,7 +852,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: '1', }, }, @@ -731,7 +910,7 @@ describe('Textbased Data Source', () => { }, }, ], - query: { sql: 'SELECT * FROM foo' }, + query: { esql: 'FROM foo' }, index: '1', }, }, @@ -759,11 +938,14 @@ describe('Textbased Data Source', () => { }, Object { "arguments": Object { + "locale": Array [ + "en", + ], "query": Array [ - "SELECT * FROM foo", + "FROM foo", ], }, - "function": "essql", + "function": "esql", "type": "function", }, Object { diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index 43d971caf24a..a24c52b88d21 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -42,10 +42,10 @@ import type { } from './types'; import { FieldSelect } from './field_select'; import type { Datasource } from '../../types'; -import { LayerPanel } from './layerpanel'; import { getUniqueLabelGenerator, nonNullable } from '../../utils'; import { onDrop, getDropProps } from './dnd'; import { removeColumn } from './remove_column'; +import { canColumnBeUsedBeInMetricDimension, MAX_NUM_OF_COLUMNS } from './utils'; function getLayerReferenceName(layerId: string) { return `textBasedLanguages-datasource-layer-${layerId}`; @@ -88,12 +88,20 @@ export function getTextBasedDatasource({ layerId: id, columns: layer.columns?.map((f) => { + const inMetricDimension = canColumnBeUsedBeInMetricDimension( + layer.allColumns, + f?.meta?.type + ); return { columnId: f.columnId, operation: { dataType: f?.meta?.type as DataType, label: f.fieldName, isBucketed: Boolean(f?.meta?.type !== 'number'), + // makes non-number fields to act as metrics, used for datatable suggestions + ...(inMetricDimension && { + inMetricDimension, + }), }, }; }) ?? [], @@ -113,11 +121,23 @@ export function getTextBasedDatasource({ if (context && 'dataViewSpec' in context && context.dataViewSpec.title && context.query) { const newLayerId = generateId(); const textBasedQueryColumns = context.textBasedColumns ?? []; + // Number fields are assigned automatically as metrics (!isBucketed). There are cases where the query + // will not return number fields. In these cases we want to suggest a datatable + // Datatable works differently in this case. On the metrics dimension can be all type of fields + const hasNumberTypeColumns = textBasedQueryColumns?.some((c) => c?.meta?.type === 'number'); const newColumns = textBasedQueryColumns.map((c) => { + const inMetricDimension = canColumnBeUsedBeInMetricDimension( + textBasedQueryColumns, + c?.meta?.type + ); return { columnId: c.id, fieldName: c.name, meta: c.meta, + // makes non-number fields to act as metrics, used for datatable suggestions + ...(inMetricDimension && { + inMetricDimension, + }), }; }); @@ -126,12 +146,23 @@ export function getTextBasedDatasource({ const updatedState = { ...state, fieldList: textBasedQueryColumns, + ...(context.dataViewSpec.id + ? { + indexPatternRefs: [ + { + id: context.dataViewSpec.id, + title: context.dataViewSpec.title, + timeField: context.dataViewSpec.timeFieldName, + }, + ], + } + : {}), layers: { ...state.layers, [newLayerId]: { index, query, - columns: newColumns ?? [], + columns: newColumns.slice(0, MAX_NUM_OF_COLUMNS) ?? [], allColumns: newColumns ?? [], timeField: context.dataViewSpec.timeFieldName, }, @@ -146,9 +177,10 @@ export function getTextBasedDatasource({ table: { changeType: 'initial' as TableChangeType, isMultiRow: false, + notAssignedMetrics: !hasNumberTypeColumns, layerId: newLayerId, columns: - newColumns?.map((f) => { + newColumns?.slice(0, MAX_NUM_OF_COLUMNS)?.map((f) => { return { columnId: f.columnId, operation: { @@ -304,6 +336,13 @@ export function getTextBasedDatasource({ getLayers(state: TextBasedPrivateState) { return state && state.layers ? Object.keys(state?.layers) : []; }, + // there are cases where a query can return a big amount of columns + // at this case we don't suggest all columns in a table but the first + // MAX_NUM_OF_COLUMNS + suggestsLimitedColumns(state: TextBasedPrivateState) { + const fieldsList = state?.fieldList ?? []; + return fieldsList.length >= MAX_NUM_OF_COLUMNS; + }, isTimeBased: (state, indexPatterns) => { if (!state) return false; const { layers } = state; @@ -382,20 +421,21 @@ export function getTextBasedDatasource({ DimensionEditorComponent: (props: DatasourceDimensionEditorProps) => { const fields = props.state.fieldList; - const selectedField = props.state.layers[props.layerId]?.allColumns?.find( - (column) => column.columnId === props.columnId - ); + const allColumns = props.state.layers[props.layerId]?.allColumns; + const selectedField = allColumns?.find((column) => column.columnId === props.columnId); + const hasNumberTypeColumns = allColumns?.some((c) => c?.meta?.type === 'number'); const updatedFields = fields?.map((f) => { return { ...f, - compatible: props.isMetricDimension - ? props.filterOperations({ - dataType: f.meta.type as DataType, - isBucketed: Boolean(f?.meta?.type !== 'number'), - scale: 'ordinal', - }) - : true, + compatible: + props.isMetricDimension && hasNumberTypeColumns + ? props.filterOperations({ + dataType: f.meta.type as DataType, + isBucketed: Boolean(f?.meta?.type !== 'number'), + scale: 'ordinal', + }) + : true, }; }); return ( @@ -472,7 +512,7 @@ export function getTextBasedDatasource({ }, LayerPanelComponent: (props: DatasourceLayerPanelProps) => { - return ; + return null; }, uniqueLabels(state: TextBasedPrivateState) { @@ -519,6 +559,7 @@ export function getTextBasedDatasource({ dataType: column?.meta?.type as DataType, label: columnLabelMap[columnId] ?? column?.fieldName, isBucketed: Boolean(column?.meta?.type !== 'number'), + inMetricDimension: column.inMetricDimension, hasTimeShift: false, hasReducedTimeRange: false, }; diff --git a/x-pack/plugins/lens/public/datasources/text_based/types.ts b/x-pack/plugins/lens/public/datasources/text_based/types.ts index 8da183f9b905..4d1f9dfea510 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/types.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/types.ts @@ -13,6 +13,7 @@ export interface TextBasedLayerColumn { columnId: string; fieldName: string; meta?: DatatableColumn['meta']; + inMetricDimension?: boolean; } export interface TextBasedField { diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts index 593d34f45021..3a01a7ba9efe 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts @@ -15,6 +15,7 @@ import { loadIndexPatternRefs, getStateFromAggregateQuery, getAllColumns, + canColumnBeUsedBeInMetricDimension, } from './utils'; import type { TextBasedLayerColumn } from './types'; import { type AggregateQuery } from '@kbn/es-query'; @@ -485,4 +486,111 @@ describe('Text based languages utils', () => { }); }); }); + + describe('canColumnBeUsedBeInMetricDimension', () => { + it('should return true if there are non numeric field', async () => { + const fieldList = [ + { + id: 'a', + name: 'Test 1', + meta: { + type: 'string', + }, + }, + { + id: 'b', + name: 'Test 2', + meta: { + type: 'string', + }, + }, + ] as DatatableColumn[]; + const flag = canColumnBeUsedBeInMetricDimension(fieldList, 'string'); + expect(flag).toBeTruthy(); + }); + + it('should return true if there are numeric field and the selected type is number', async () => { + const fieldList = [ + { + id: 'a', + name: 'Test 1', + meta: { + type: 'number', + }, + }, + { + id: 'b', + name: 'Test 2', + meta: { + type: 'string', + }, + }, + ] as DatatableColumn[]; + const flag = canColumnBeUsedBeInMetricDimension(fieldList, 'number'); + expect(flag).toBeTruthy(); + }); + + it('should return false if there are non numeric fields and the selected type is non numeric', async () => { + const fieldList = [ + { + id: 'a', + name: 'Test 1', + meta: { + type: 'number', + }, + }, + { + id: 'b', + name: 'Test 2', + meta: { + type: 'string', + }, + }, + ] as DatatableColumn[]; + const flag = canColumnBeUsedBeInMetricDimension(fieldList, 'date'); + expect(flag).toBeFalsy(); + }); + + it('should return true if there are many columns regardless the types', async () => { + const fieldList = [ + { + id: 'a', + name: 'Test 1', + meta: { + type: 'number', + }, + }, + { + id: 'b', + name: 'Test 2', + meta: { + type: 'number', + }, + }, + { + id: 'c', + name: 'Test 3', + meta: { + type: 'date', + }, + }, + { + id: 'd', + name: 'Test 4', + meta: { + type: 'string', + }, + }, + { + id: 'e', + name: 'Test 5', + meta: { + type: 'string', + }, + }, + ] as DatatableColumn[]; + const flag = canColumnBeUsedBeInMetricDimension(fieldList, 'date'); + expect(flag).toBeTruthy(); + }); + }); }); diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.ts index aea93add7368..ecf4fbcd12ff 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.ts @@ -20,6 +20,8 @@ import { fetchDataFromAggregateQuery } from './fetch_data_from_aggregate_query'; import type { IndexPatternRef, TextBasedPrivateState, TextBasedLayerColumn } from './types'; import type { DataViewsState } from '../../state_management'; +export const MAX_NUM_OF_COLUMNS = 5; + export async function loadIndexPatternRefs( indexPatternsService: DataViewsPublicPluginStart ): Promise { @@ -146,3 +148,25 @@ export function getIndexPatternFromTextBasedQuery(query: AggregateQuery): string return indexPattern; } + +export function canColumnBeDroppedInMetricDimension( + columns: TextBasedLayerColumn[] | DatatableColumn[], + selectedColumnType?: string +): boolean { + // check if at least one numeric field exists + const hasNumberTypeColumns = columns?.some((c) => c?.meta?.type === 'number'); + return !hasNumberTypeColumns || (hasNumberTypeColumns && selectedColumnType === 'number'); +} + +export function canColumnBeUsedBeInMetricDimension( + columns: TextBasedLayerColumn[] | DatatableColumn[], + selectedColumnType?: string +): boolean { + // check if at least one numeric field exists + const hasNumberTypeColumns = columns?.some((c) => c?.meta?.type === 'number'); + return ( + !hasNumberTypeColumns || + columns.length >= MAX_NUM_OF_COLUMNS || + (hasNumberTypeColumns && selectedColumnType === 'number') + ); +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 41184d2212c4..8c31fb2f9d80 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -370,7 +370,7 @@ export function LayerPanels( } }, registerLibraryAnnotationGroup: registerLibraryAnnotationGroupFunction, - isInlineEditing: Boolean(props?.setIsInlineFlyoutFooterVisible), + isInlineEditing: Boolean(props?.setIsInlineFlyoutVisible), })} ); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 78a06408902b..024fb04998d3 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -95,7 +95,7 @@ export function LayerPanel( indexPatternService?: IndexPatternServiceAPI; getUserMessages?: UserMessagesGetter; displayLayerSettings: boolean; - setIsInlineFlyoutFooterVisible?: (status: boolean) => void; + setIsInlineFlyoutVisible?: (status: boolean) => void; } ) { const [activeDimension, setActiveDimension] = useState( @@ -139,7 +139,7 @@ export function LayerPanel( useEffect(() => { // is undefined when the dimension panel is closed const activeDimensionId = activeDimension.activeId; - props?.setIsInlineFlyoutFooterVisible?.(!Boolean(activeDimensionId)); + props?.setIsInlineFlyoutVisible?.(!Boolean(activeDimensionId)); }, [activeDimension.activeId, activeVisualization.id, props]); const panelRef = useRef(null); @@ -394,6 +394,7 @@ export function LayerPanel( )} {props.indexPatternService && + !isTextBasedLanguage && (layerDatasource || activeVisualization.LayerPanelComponent) && ( )} @@ -680,7 +681,7 @@ export function LayerPanel( setPanelSettingsOpen(false); return true; }} - isInlineEditing={Boolean(props?.setIsInlineFlyoutFooterVisible)} + isInlineEditing={Boolean(props?.setIsInlineFlyoutVisible)} >
    @@ -749,7 +750,7 @@ export function LayerPanel( isOpen={isDimensionPanelOpen} isFullscreen={isFullscreen} groupLabel={activeGroup?.dimensionEditorGroupLabel ?? (activeGroup?.groupLabel || '')} - isInlineEditing={Boolean(props?.setIsInlineFlyoutFooterVisible)} + isInlineEditing={Boolean(props?.setIsInlineFlyoutVisible)} handleClose={() => { if (layerDatasource) { if (layerDatasource.updateStateOnCloseDimension) { @@ -828,7 +829,7 @@ export function LayerPanel( addLayer: props.addLayer, removeLayer: props.onRemoveLayer, panelRef, - isInlineEditing: Boolean(props?.setIsInlineFlyoutFooterVisible), + isInlineEditing: Boolean(props?.setIsInlineFlyoutVisible), }} />
    diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts index 6d06dfb7e6aa..2ef775b51f54 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/types.ts @@ -29,7 +29,7 @@ export interface ConfigPanelWrapperProps { uiActions: UiActionsStart; getUserMessages?: UserMessagesGetter; hideLayerHeader?: boolean; - setIsInlineFlyoutFooterVisible?: (status: boolean) => void; + setIsInlineFlyoutVisible?: (status: boolean) => void; } export interface LayerPanelProps { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts index c1032d144ac3..fd2868b8a406 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_helpers.ts @@ -150,6 +150,7 @@ export function getSuggestions({ return filteredCount || filteredCount === datasourceSuggestion.keptLayerIds.length; }) .flatMap((datasourceSuggestion) => { + const datasourceId = datasourceSuggestion.datasourceId; const table = datasourceSuggestion.table; const currentVisualizationState = visualizationId === activeVisualization?.id ? visualizationState : undefined; @@ -170,7 +171,8 @@ export function getSuggestions({ palette, visualizeTriggerFieldContext && 'isVisualizeAction' in visualizeTriggerFieldContext, activeData, - allowMixed + allowMixed, + datasourceId ); }); }) @@ -240,7 +242,8 @@ function getVisualizationSuggestions( mainPalette?: SuggestionRequest['mainPalette'], isFromContext?: boolean, activeData?: Record, - allowMixed?: boolean + allowMixed?: boolean, + datasourceId?: string ) { try { return visualization @@ -253,6 +256,7 @@ function getVisualizationSuggestions( isFromContext, activeData, allowMixed, + datasourceId, }) .map(({ state, ...visualizationSuggestion }) => ({ ...visualizationSuggestion, diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss index f139bbe3ca12..cd2ee706c1e1 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.scss @@ -1,6 +1,10 @@ @import '../../mixins'; @import '../../variables'; +.lnsSuggestionPanel .euiAccordion__buttonContent { + width: 100%; +} + .lnsSuggestionPanel__suggestions { @include euiScrollBar; @include lnsOverflowShadowHorizontal; @@ -16,14 +20,9 @@ margin-right: -$euiSizeXS; } -.lnsSuggestionPanel { - padding-bottom: $euiSizeS; -} - .lnsSuggestionPanel__button { position: relative; // Let the expression progress indicator position itself against the button flex: 0 0 auto; - width: $lnsSuggestionWidth !important; // sass-lint:disable-line no-important height: $lnsSuggestionHeight; margin-right: $euiSizeS; margin-left: $euiSizeXS / 2; @@ -58,6 +57,10 @@ } } +.lnsSuggestionPanel__button-fixedWidth { + width: $lnsSuggestionWidth !important; // sass-lint:disable-line no-important +} + .lnsSuggestionPanel__suggestionIcon { color: $euiColorDarkShade; width: 100%; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index a4e65b280d20..c487f31fd82f 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -10,6 +10,7 @@ import './suggestion_panel.scss'; import { camelCase, pick } from 'lodash'; import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { css } from '@emotion/react'; import useLocalStorage from 'react-use/lib/useLocalStorage'; import { EuiIcon, @@ -20,7 +21,9 @@ import { EuiButtonEmpty, EuiAccordion, EuiText, + EuiNotificationBadge, } from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; import { IconType } from '@elastic/eui/src/components/icon/icon'; import { Ast, fromExpression, toExpression } from '@kbn/interpreter'; import { i18n } from '@kbn/i18n'; @@ -65,6 +68,7 @@ import { selectFramePublicAPI, } from '../../state_management'; import { filterAndSortUserMessages } from '../../app_plugin/get_application_user_messages'; + const MAX_SUGGESTIONS_DISPLAYED = 5; const LOCAL_STORAGE_SUGGESTIONS_PANEL = 'LENS_SUGGESTIONS_PANEL_HIDDEN'; @@ -99,10 +103,13 @@ export interface SuggestionPanelProps { visualizationMap: VisualizationMap; ExpressionRenderer: ReactExpressionRendererType; frame: FramePublicAPI; - getUserMessages: UserMessagesGetter; + getUserMessages?: UserMessagesGetter; nowProvider: DataPublicPluginStart['nowProvider']; core: CoreStart; showOnlyIcons?: boolean; + wrapSuggestions?: boolean; + isAccordionOpen?: boolean; + toggleAccordionCb?: (flag: boolean) => void; } const PreviewRenderer = ({ @@ -165,6 +172,7 @@ const SuggestionPreview = ({ onSelect, showTitleAsLabel, onRender, + wrapSuggestions, }: { onSelect: () => void; preview: { @@ -177,15 +185,30 @@ const SuggestionPreview = ({ selected: boolean; showTitleAsLabel?: boolean; onRender: () => void; + wrapSuggestions?: boolean; }) => { return ( - +
    selectFramePublicAPI(state, datasourceMap)); const changesApplied = useLensSelector(selectChangesApplied); // get user's selection from localStorage, this key defines if the suggestions panel will be hidden or not + const initialAccordionStatusValue = + typeof isAccordionOpen !== 'undefined' ? !Boolean(isAccordionOpen) : false; const [hideSuggestions, setHideSuggestions] = useLocalStorage( LOCAL_STORAGE_SUGGESTIONS_PANEL, - false + initialAccordionStatusValue ); + useEffect(() => { + if (typeof isAccordionOpen !== 'undefined') { + setHideSuggestions(!Boolean(isAccordionOpen)); + } + }, [isAccordionOpen, setHideSuggestions]); const toggleSuggestions = useCallback(() => { setHideSuggestions(!hideSuggestions); - }, [setHideSuggestions, hideSuggestions]); + toggleAccordionCb?.(!hideSuggestions); + }, [setHideSuggestions, hideSuggestions, toggleAccordionCb]); const missingIndexPatterns = getMissingIndexPattern( activeDatasourceId ? datasourceMap[activeDatasourceId] : null, @@ -304,8 +338,10 @@ export function SuggestionPanel({ ), })); - const hasErrors = - getUserMessages(['visualization', 'visualizationInEditor'], { severity: 'error' }).length > 0; + const hasErrors = getUserMessages + ? getUserMessages(['visualization', 'visualizationInEditor'], { severity: 'error' }).length > + 0 + : false; const newStateExpression = currentVisualization.state && currentVisualization.activeId && !hasErrors @@ -450,6 +486,7 @@ export function SuggestionPanel({ selected={lastSelectedSuggestion === -1} showTitleAsLabel onRender={() => onSuggestionRender(0)} + wrapSuggestions={wrapSuggestions} /> )} {!hideSuggestions && @@ -474,64 +511,88 @@ export function SuggestionPanel({ selected={index === lastSelectedSuggestion} onRender={() => onSuggestionRender(index + 1)} showTitleAsLabel={showOnlyIcons} + wrapSuggestions={wrapSuggestions} /> ); })} ); }; - + const title = ( + +

    + +

    +
    + ); return ( -
    - -

    - -

    - - } - forceState={hideSuggestions ? 'closed' : 'open'} - onToggle={toggleSuggestions} - extraAction={ - existsStagedPreview && - !hideSuggestions && ( - - { - dispatchLens(submitSuggestion()); - }} - > - {i18n.translate('xpack.lens.sugegstion.refreshSuggestionLabel', { - defaultMessage: 'Refresh', + + {existsStagedPreview && ( + - - ) - } + > + { + dispatchLens(submitSuggestion()); + }} + > + {i18n.translate('xpack.lens.sugegstion.refreshSuggestionLabel', { + defaultMessage: 'Refresh', + })} + + + )} + {wrapSuggestions && ( + + {suggestions.length + 1} + + )} + + ) + } + > +
    -
    - {changesApplied ? renderSuggestionsUI() : renderApplyChangesPrompt()} -
    - -
    + {changesApplied ? renderSuggestionsUI() : renderApplyChangesPrompt()} +
    + ); } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss index 391361570d04..2c0d374a7d07 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.scss @@ -149,3 +149,10 @@ 75% { transform: translateY(15%); } 100% { transform: translateY(10%); } } + +.lnsVisualizationToolbar--fixed { + position: fixed; + width: 100%; + z-index: 1; + background-color: $euiColorLightestShade; +} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index ea2c8d27086f..f5ee47cbcd29 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -53,10 +53,11 @@ export interface WorkspacePanelWrapperProps { export function VisualizationToolbar(props: { activeVisualization: Visualization | null; framePublicAPI: FramePublicAPI; + isFixedPosition?: boolean; }) { const dispatchLens = useLensDispatch(); const visualization = useLensSelector(selectVisualizationState); - const { activeVisualization } = props; + const { activeVisualization, isFixedPosition } = props; const setVisualizationState = useCallback( (newState: unknown) => { if (!activeVisualization) { @@ -77,7 +78,12 @@ export function VisualizationToolbar(props: { return ( <> {ToolbarComponent && ( - + {ToolbarComponent({ frame: props.framePublicAPI, state: visualization.state, diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index bb99e061893f..16d730139c14 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -747,7 +747,11 @@ export class Embeddable * Gets the Lens embeddable's datasource and visualization states * updates the embeddable input */ - async updateVisualization(datasourceState: unknown, visualizationState: unknown) { + async updateVisualization( + datasourceState: unknown, + visualizationState: unknown, + visualizationType?: string + ) { const viz = this.savedVis; const activeDatasourceId = (this.activeDatasourceId ?? 'formBased') as EditLensConfigurationProps['datasourceId']; @@ -769,7 +773,7 @@ export class Embeddable ), visualizationState, activeVisualization: this.activeVisualizationId - ? this.deps.visualizationMap[this.activeVisualizationId] + ? this.deps.visualizationMap[visualizationType ?? this.activeVisualizationId] : undefined, }); const attrs = { @@ -780,6 +784,7 @@ export class Embeddable datasourceStates, }, references, + visualizationType: visualizationType ?? viz.visualizationType, }; /** @@ -795,6 +800,15 @@ export class Embeddable } } + async updateSuggestion(attrs: LensSavedObjectAttributes) { + const viz = this.savedVis; + const newViz = { + ...viz, + ...attrs, + }; + this.updateInput({ attributes: newViz }); + } + /** * Callback which allows the navigation to the editor. * Used for the Edit in Lens link inside the inline editing flyout. @@ -848,6 +862,7 @@ export class Embeddable ); } diff --git a/x-pack/plugins/lens/public/mocks/dataview_mock.ts b/x-pack/plugins/lens/public/mocks/dataview_mock.ts new file mode 100644 index 000000000000..880b9a3f287d --- /dev/null +++ b/x-pack/plugins/lens/public/mocks/dataview_mock.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DataView } from '@kbn/data-views-plugin/public'; +import { buildDataViewMock } from '@kbn/discover-utils/src/__mocks__'; + +const fields = [ + { + name: '_index', + type: 'string', + scripted: false, + filterable: true, + }, + { + name: '@timestamp', + displayName: 'timestamp', + type: 'date', + scripted: false, + filterable: true, + aggregatable: true, + sortable: true, + }, + { + name: 'message', + displayName: 'message', + type: 'string', + scripted: false, + filterable: false, + }, + { + name: 'extension', + displayName: 'extension', + type: 'string', + scripted: false, + filterable: true, + aggregatable: true, + }, + { + name: 'bytes', + displayName: 'bytes', + type: 'number', + scripted: false, + filterable: true, + aggregatable: true, + }, +] as DataView['fields']; + +export const mockDataViewWithTimefield = buildDataViewMock({ + name: 'index-pattern-with-timefield', + fields, + timeFieldName: '%timestamp', +}); diff --git a/x-pack/plugins/lens/public/mocks/index.ts b/x-pack/plugins/lens/public/mocks/index.ts index 6cc3ff02ff92..f90ecc9b99fe 100644 --- a/x-pack/plugins/lens/public/mocks/index.ts +++ b/x-pack/plugins/lens/public/mocks/index.ts @@ -29,6 +29,8 @@ export { renderWithReduxStore, } from './store_mocks'; export { lensPluginMock } from './lens_plugin_mock'; +export { mockDataViewWithTimefield } from './dataview_mock'; +export { mockAllSuggestions } from './suggestions_mock'; export type FrameMock = jest.Mocked; diff --git a/x-pack/plugins/lens/public/mocks/suggestions_mock.ts b/x-pack/plugins/lens/public/mocks/suggestions_mock.ts new file mode 100644 index 000000000000..0ed32fbfd84d --- /dev/null +++ b/x-pack/plugins/lens/public/mocks/suggestions_mock.ts @@ -0,0 +1,291 @@ +/* + * 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 { Suggestion } from '../types'; + +export const currentSuggestionMock = { + title: 'Heat map', + hide: false, + score: 0.6, + previewIcon: 'heatmap', + visualizationId: 'lnsHeatmap', + visualizationState: { + shape: 'heatmap', + layerId: '46aa21fa-b747-4543-bf90-0b40007c546d', + layerType: 'data', + legend: { + isVisible: true, + position: 'right', + type: 'heatmap_legend', + }, + gridConfig: { + type: 'heatmap_grid', + isCellLabelVisible: false, + isYAxisLabelVisible: true, + isXAxisLabelVisible: true, + isYAxisTitleVisible: false, + isXAxisTitleVisible: false, + }, + valueAccessor: '5b9b8b76-0836-4a12-b9c0-980c9900502f', + xAccessor: '81e332d6-ee37-42a8-a646-cea4fc75d2d3', + }, + keptLayerIds: ['46aa21fa-b747-4543-bf90-0b40007c546d'], + datasourceState: { + layers: { + '46aa21fa-b747-4543-bf90-0b40007c546d': { + index: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + query: { + esql: 'FROM kibana_sample_data_flights | keep Dest, AvgTicketPrice', + }, + columns: [ + { + columnId: '81e332d6-ee37-42a8-a646-cea4fc75d2d3', + fieldName: 'Dest', + meta: { + type: 'string', + }, + }, + { + columnId: '5b9b8b76-0836-4a12-b9c0-980c9900502f', + fieldName: 'AvgTicketPrice', + meta: { + type: 'number', + }, + }, + ], + allColumns: [ + { + columnId: '81e332d6-ee37-42a8-a646-cea4fc75d2d3', + fieldName: 'Dest', + meta: { + type: 'string', + }, + }, + { + columnId: '5b9b8b76-0836-4a12-b9c0-980c9900502f', + fieldName: 'AvgTicketPrice', + meta: { + type: 'number', + }, + }, + ], + timeField: 'timestamp', + }, + }, + fieldList: [], + indexPatternRefs: [], + initialContext: { + dataViewSpec: { + id: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + version: 'WzM1ODA3LDFd', + title: 'kibana_sample_data_flights', + timeFieldName: 'timestamp', + sourceFilters: [], + fields: { + AvgTicketPrice: { + count: 0, + name: 'AvgTicketPrice', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'number', + params: { + pattern: '$0,0.[00]', + }, + }, + shortDotsEnable: false, + isMapped: true, + }, + Dest: { + count: 0, + name: 'Dest', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'string', + }, + shortDotsEnable: false, + isMapped: true, + }, + timestamp: { + count: 0, + name: 'timestamp', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'date', + }, + shortDotsEnable: false, + isMapped: true, + }, + }, + allowNoIndex: false, + name: 'Kibana Sample Data Flights', + }, + fieldName: '', + contextualFields: ['Dest', 'AvgTicketPrice'], + query: { + esql: 'FROM "kibana_sample_data_flights"', + }, + }, + }, + datasourceId: 'textBased', + columns: 2, + changeType: 'initial', +} as Suggestion; + +export const mockAllSuggestions = [ + currentSuggestionMock, + { + title: 'Donut', + score: 0.46, + visualizationId: 'lnsPie', + previewIcon: 'pie', + visualizationState: { + shape: 'donut', + layers: [ + { + layerId: '2513a3d4-ad9d-48ea-bd58-8b6419ab97e6', + primaryGroups: ['923f0681-3fe1-4987-aa27-d9c91fb95fa6'], + metrics: ['b5f41c04-4bca-4abe-ae5c-b1d4d6fb00e0'], + numberDisplay: 'percent', + categoryDisplay: 'default', + legendDisplay: 'default', + nestedLegend: false, + layerType: 'data', + }, + ], + }, + keptLayerIds: ['2513a3d4-ad9d-48ea-bd58-8b6419ab97e6'], + datasourceState: { + layers: { + '2513a3d4-ad9d-48ea-bd58-8b6419ab97e6': { + index: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + query: { + esql: 'FROM "kibana_sample_data_flights"', + }, + columns: [ + { + columnId: '923f0681-3fe1-4987-aa27-d9c91fb95fa6', + fieldName: 'Dest', + meta: { + type: 'string', + }, + }, + { + columnId: 'b5f41c04-4bca-4abe-ae5c-b1d4d6fb00e0', + fieldName: 'AvgTicketPrice', + meta: { + type: 'number', + }, + }, + ], + allColumns: [ + { + columnId: '923f0681-3fe1-4987-aa27-d9c91fb95fa6', + fieldName: 'Dest', + meta: { + type: 'string', + }, + }, + { + columnId: 'b5f41c04-4bca-4abe-ae5c-b1d4d6fb00e0', + fieldName: 'AvgTicketPrice', + meta: { + type: 'number', + }, + }, + ], + timeField: 'timestamp', + }, + }, + fieldList: [], + indexPatternRefs: [], + initialContext: { + dataViewSpec: { + id: 'd3d7af60-4c81-11e8-b3d7-01146121b73d', + version: 'WzM1ODA3LDFd', + title: 'kibana_sample_data_flights', + timeFieldName: 'timestamp', + sourceFilters: [], + fields: { + AvgTicketPrice: { + count: 0, + name: 'AvgTicketPrice', + type: 'number', + esTypes: ['float'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'number', + params: { + pattern: '$0,0.[00]', + }, + }, + shortDotsEnable: false, + isMapped: true, + }, + Dest: { + count: 0, + name: 'Dest', + type: 'string', + esTypes: ['keyword'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'string', + }, + shortDotsEnable: false, + isMapped: true, + }, + timestamp: { + count: 0, + name: 'timestamp', + type: 'date', + esTypes: ['date'], + scripted: false, + searchable: true, + aggregatable: true, + readFromDocValues: true, + format: { + id: 'date', + }, + shortDotsEnable: false, + isMapped: true, + }, + }, + typeMeta: {}, + allowNoIndex: false, + name: 'Kibana Sample Data Flights', + }, + fieldName: '', + contextualFields: ['Dest', 'AvgTicketPrice'], + query: { + esql: 'FROM "kibana_sample_data_flights"', + }, + }, + }, + datasourceId: 'textBased', + columns: 2, + changeType: 'unchanged', + } as Suggestion, +]; diff --git a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.scss b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.scss index 56cfe41c4b88..6572fd969a5b 100644 --- a/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.scss +++ b/x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.scss @@ -1,6 +1,7 @@ // styles needed to display extra drop targets that are outside of the config panel main area while also allowing to scroll vertically .lnsConfigPanel__overlay { clip-path: polygon(-100% 0, 100% 0, 100% 100%, -100% 100%); + background: $euiColorLightestShade; .kbnOverlayMountWrapper { padding-left: $euiFormMaxWidth; margin-left: -$euiFormMaxWidth; 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 b1647876581f..8fd011fddfb2 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 @@ -52,6 +52,7 @@ export async function executeAction({ embeddable, startDependencies, overlays, t size: 's', 'data-test-subj': 'customizeLens', type: 'push', + paddingSize: 'm', hideCloseButton: true, onClose: (overlayRef) => { if (overlayTracker) overlayTracker.clearOverlays(); diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 25b637aebf07..e5c9fad96d6c 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -198,6 +198,8 @@ export interface TableSuggestion { * The change type indicates what was changed in this table compared to the currently active table of this layer. */ changeType: TableChangeType; + + notAssignedMetrics?: boolean; } /** @@ -509,6 +511,8 @@ export interface Datasource { ) => Promise; injectReferencesToLayers?: (state: T, references?: SavedObjectReference[]) => T; + + suggestsLimitedColumns?: (state: T) => boolean; } export interface DatasourceFixAction { @@ -746,6 +750,7 @@ export interface OperationMetadata { export interface OperationDescriptor extends Operation { hasTimeShift: boolean; hasReducedTimeRange: boolean; + inMetricDimension?: boolean; } export interface VisualizationConfigProps { @@ -882,6 +887,7 @@ export interface SuggestionRequest { subVisualizationId?: string; activeData?: Record; allowMixed?: boolean; + datasourceId?: string; } /** diff --git a/x-pack/plugins/lens/public/vis_type_alias.ts b/x-pack/plugins/lens/public/vis_type_alias.ts index 2fc493df38ed..20822ee76a09 100644 --- a/x-pack/plugins/lens/public/vis_type_alias.ts +++ b/x-pack/plugins/lens/public/vis_type_alias.ts @@ -11,8 +11,10 @@ import { getBasePath, getEditPath } from '../common/constants'; import { getLensClient } from './persistence/lens_client'; export const getLensAliasConfig = (): VisTypeAlias => ({ - aliasPath: getBasePath(), - aliasApp: 'lens', + alias: { + path: getBasePath(), + app: 'lens', + }, name: 'lens', promotion: true, title: i18n.translate('xpack.lens.visTypeAlias.title', { @@ -41,8 +43,7 @@ export const getLensAliasConfig = (): VisTypeAlias => ({ title, description, updatedAt, - editUrl: getEditPath(id), - editApp: 'lens', + editor: { editUrl: getEditPath(id), editApp: 'lens' }, icon: 'lensApp', stage: 'production', savedObjectType: type, diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx index a6810e77d438..a3f4f6f797ee 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.test.tsx @@ -138,6 +138,26 @@ describe('Datatable Visualization', () => { expect(suggestions.length).toBeGreaterThan(0); }); + it('should force table as suggestion when there are no number fields', () => { + const suggestions = datatableVisualization.getSuggestions({ + state: { + layerId: 'first', + layerType: LayerTypes.DATA, + columns: [{ columnId: 'col1' }], + }, + table: { + isMultiRow: true, + layerId: 'first', + changeType: 'initial', + columns: [strCol('col1'), strCol('col2')], + notAssignedMetrics: true, + }, + keptLayerIds: [], + }); + + expect(suggestions.length).toBeGreaterThan(0); + }); + it('should reject suggestion with static value', () => { function staticValueCol(columnId: string): TableSuggestionColumn { return { @@ -387,6 +407,48 @@ describe('Datatable Visualization', () => { }).groups[2].accessors ).toEqual([{ columnId: 'c' }, { columnId: 'b' }]); }); + + it('should compute the groups correctly for text based languages', () => { + const datasource = createMockDatasource('textBased', { + isTextBasedLanguage: jest.fn(() => true), + }); + datasource.publicAPIMock.getTableSpec.mockReturnValue([ + { columnId: 'c', fields: [] }, + { columnId: 'b', fields: [] }, + ]); + const frame = mockFrame(); + frame.datasourceLayers = { first: datasource.publicAPIMock }; + + const groups = datatableVisualization.getConfiguration({ + layerId: 'first', + state: { + layerId: 'first', + layerType: LayerTypes.DATA, + columns: [{ columnId: 'b', isMetric: true }, { columnId: 'c' }], + }, + frame, + }).groups; + + // rows + expect(groups[0].accessors).toEqual([ + { + columnId: 'c', + triggerIconType: undefined, + }, + ]); + + // columns + expect(groups[1].accessors).toEqual([]); + + // metrics + expect(groups[2].accessors).toEqual([ + { + columnId: 'b', + triggerIconType: undefined, + palette: undefined, + }, + ]); + }); }); describe('#removeDimension', () => { @@ -462,7 +524,11 @@ describe('Datatable Visualization', () => { ).toEqual({ layerId: 'layer1', layerType: LayerTypes.DATA, - columns: [{ columnId: 'b' }, { columnId: 'c' }, { columnId: 'd', isTransposed: false }], + columns: [ + { columnId: 'b' }, + { columnId: 'c' }, + { columnId: 'd', isTransposed: false, isMetric: false }, + ], }); }); @@ -482,7 +548,7 @@ describe('Datatable Visualization', () => { ).toEqual({ layerId: 'layer1', layerType: LayerTypes.DATA, - columns: [{ columnId: 'b', isTransposed: false }, { columnId: 'c' }], + columns: [{ columnId: 'b', isTransposed: false, isMetric: false }, { columnId: 'c' }], }); }); }); diff --git a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx index 35757771af75..505b20bdc3e5 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/visualization.tsx @@ -165,11 +165,14 @@ export const getDatatableVisualization = ({ ? 0.5 : 1; + // forcing datatable as a suggestion when there are no metrics (number fields) + const forceSuggestion = Boolean(table?.notAssignedMetrics); + return [ { title, // table with >= 10 columns will have a score of 0.4, fewer columns reduce score - score: (Math.min(table.columns.length, 10) / 10) * 0.4 * changeFactor, + score: forceSuggestion ? 1 : (Math.min(table.columns.length, 10) / 10) * 0.4 * changeFactor, state: { ...(state || {}), layerId: table.layerId, @@ -187,6 +190,13 @@ export const getDatatableVisualization = ({ ]; }, + /* + Datatable works differently on text based datasource and form based + - Form based: It relies on the isBucketed flag to identify groups. It allows only numeric fields + on the Metrics dimension + - Text based: It relies on the isMetric flag to identify groups. It allows all type of fields + on the Metric dimension in cases where there are no numeric columns + **/ getConfiguration({ state, frame, layerId }) { const { sortedColumns, datasource } = getDataSourceAndSortedColumns(state, frame.datasourceLayers, layerId) || {}; @@ -199,9 +209,11 @@ export const getDatatableVisualization = ({ if (!sortedColumns) { return { groups: [] }; } + const isTextBasedLanguage = datasource?.isTextBasedLanguage(); return { groups: [ + // In this group we get columns that are not transposed and are not on the metric dimension { groupId: 'rows', groupLabel: i18n.translate('xpack.lens.datatable.breakdownRows', { @@ -216,11 +228,17 @@ export const getDatatableVisualization = ({ }), layerId: state.layerId, accessors: sortedColumns - .filter( - (c) => - datasource!.getOperationForColumnId(c)?.isBucketed && - !state.columns.find((col) => col.columnId === c)?.isTransposed - ) + .filter((c) => { + const column = state.columns.find((col) => col.columnId === c); + if (isTextBasedLanguage) { + return ( + !datasource!.getOperationForColumnId(c)?.inMetricDimension && + !column?.isMetric && + !column?.isTransposed + ); + } + return datasource!.getOperationForColumnId(c)?.isBucketed && !column?.isTransposed; + }) .map((accessor) => ({ columnId: accessor, triggerIconType: columnMap[accessor].hidden @@ -236,6 +254,7 @@ export const getDatatableVisualization = ({ hideGrouping: true, nestingOrder: 1, }, + // In this group we get columns that are transposed and are not on the metric dimension { groupId: 'columns', groupLabel: i18n.translate('xpack.lens.datatable.breakdownColumns', { @@ -250,11 +269,15 @@ export const getDatatableVisualization = ({ }), layerId: state.layerId, accessors: sortedColumns - .filter( - (c) => + .filter((c) => { + if (isTextBasedLanguage) { + return state.columns.find((col) => col.columnId === c)?.isTransposed; + } + return ( datasource!.getOperationForColumnId(c)?.isBucketed && state.columns.find((col) => col.columnId === c)?.isTransposed - ) + ); + }) .map((accessor) => ({ columnId: accessor })), supportsMoreColumns: true, filterOperations: (op) => op.isBucketed, @@ -263,6 +286,7 @@ export const getDatatableVisualization = ({ hideGrouping: true, nestingOrder: 0, }, + // In this group we get columns are on the metric dimension { groupId: 'metrics', groupLabel: i18n.translate('xpack.lens.datatable.metrics', { @@ -278,7 +302,16 @@ export const getDatatableVisualization = ({ }, layerId: state.layerId, accessors: sortedColumns - .filter((c) => !datasource!.getOperationForColumnId(c)?.isBucketed) + .filter((c) => { + const operation = datasource!.getOperationForColumnId(c); + if (isTextBasedLanguage) { + return ( + operation?.inMetricDimension || + state.columns.find((col) => col.columnId === c)?.isMetric + ); + } + return !operation?.isBucketed; + }) .map((accessor) => { const columnConfig = columnMap[accessor]; const stops = columnConfig?.palette?.params?.stops; @@ -316,7 +349,12 @@ export const getDatatableVisualization = ({ ...prevState, columns: prevState.columns.map((column) => { if (column.columnId === columnId || column.columnId === previousColumn) { - return { ...column, columnId, isTransposed: groupId === 'columns' }; + return { + ...column, + columnId, + isTransposed: groupId === 'columns', + isMetric: groupId === 'metrics', + }; } return column; }), @@ -324,7 +362,10 @@ export const getDatatableVisualization = ({ } return { ...prevState, - columns: [...prevState.columns, { columnId, isTransposed: groupId === 'columns' }], + columns: [ + ...prevState.columns, + { columnId, isTransposed: groupId === 'columns', isMetric: groupId === 'metrics' }, + ], }; }, removeDimension({ prevState, columnId }) { @@ -371,9 +412,11 @@ export const getDatatableVisualization = ({ ): Ast | null { const { sortedColumns, datasource } = getDataSourceAndSortedColumns(state, datasourceLayers, state.layerId) || {}; + const isTextBasedLanguage = datasource?.isTextBasedLanguage(); if ( sortedColumns?.length && + !isTextBasedLanguage && sortedColumns.filter((c) => !datasource!.getOperationForColumnId(c)?.isBucketed).length === 0 ) { return null; @@ -435,6 +478,15 @@ export const getDatatableVisualization = ({ const canColor = datasource!.getOperationForColumnId(column.columnId)?.dataType === 'number'; + let isTransposable = + !isTextBasedLanguage && + !datasource!.getOperationForColumnId(column.columnId)?.isBucketed; + + if (isTextBasedLanguage) { + const operation = datasource!.getOperationForColumnId(column.columnId); + isTransposable = Boolean(column?.isMetric || operation?.inMetricDimension); + } + const datatableColumnFn = buildExpressionFunction( 'lens_datatable_column', { @@ -443,8 +495,7 @@ export const getDatatableVisualization = ({ oneClickFilter: column.oneClickFilter, width: column.width, isTransposed: column.isTransposed, - transposable: !datasource!.getOperationForColumnId(column.columnId)?.isBucketed, - alignment: column.alignment, + transposable: isTransposable, colorMode: canColor && column.colorMode ? column.colorMode : 'none', palette: paletteService.get(CUSTOM_PALETTE).toExpression(paletteParams), summaryRow: hasNoSummaryRow ? undefined : column.summaryRow!, diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.test.ts b/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.test.ts index ff631ee605a5..8a89bca65a2d 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.test.ts +++ b/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.test.ts @@ -305,6 +305,70 @@ describe('heatmap suggestions', () => { }, ]); }); + + test('when no metric dimension but groups', () => { + expect( + getSuggestions({ + table: { + layerId: 'first', + isMultiRow: true, + columns: [ + { + columnId: 'date-column', + operation: { + isBucketed: true, + dataType: 'date', + scale: 'interval', + label: 'Date', + }, + }, + { + columnId: 'string-column-01', + operation: { + isBucketed: true, + dataType: 'string', + label: 'Bucket 1', + }, + }, + ], + changeType: 'initial', + }, + state: { + layerId: 'first', + layerType: LayerTypes.DATA, + } as HeatmapVisualizationState, + keptLayerIds: ['first'], + }) + ).toEqual([ + { + state: { + layerId: 'first', + layerType: LayerTypes.DATA, + shape: 'heatmap', + xAccessor: 'date-column', + yAccessor: 'string-column-01', + gridConfig: { + type: HEATMAP_GRID_FUNCTION, + isCellLabelVisible: false, + isYAxisLabelVisible: true, + isXAxisLabelVisible: true, + isYAxisTitleVisible: false, + isXAxisTitleVisible: false, + }, + legend: { + isVisible: true, + position: Position.Right, + type: LEGEND_FUNCTION, + }, + }, + title: 'Heat map', + hide: true, + incomplete: true, + previewIcon: IconChartHeatmap, + score: 0, + }, + ]); + }); test('for tables with a single bucket dimension', () => { expect( getSuggestions({ diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.ts b/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.ts index ccb9c1014c25..3f748485bdb0 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/heatmap/suggestions.ts @@ -61,6 +61,7 @@ export const getSuggestions: Visualization['getSugges const isSingleBucketDimension = groups.length === 1 && metrics.length === 0; const isOnlyMetricDimension = groups.length === 0 && metrics.length === 1; + const isOnlyBucketDimension = groups.length > 0 && metrics.length === 0; /** * Hide for: @@ -77,6 +78,7 @@ export const getSuggestions: Visualization['getSugges table.changeType === 'reorder' || isSingleBucketDimension || hasOnlyDatehistogramBuckets || + isOnlyBucketDimension || isOnlyMetricDimension; const newState: HeatmapVisualizationState = { @@ -130,7 +132,7 @@ export const getSuggestions: Visualization['getSugges hide, previewIcon: IconChartHeatmap, score: Number(score.toFixed(1)), - incomplete: isSingleBucketDimension || isOnlyMetricDimension, + incomplete: isSingleBucketDimension || isOnlyMetricDimension || isOnlyBucketDimension, }, ]; }; diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.test.ts b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.test.ts index e1803e106f2e..e4b4dc187945 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.test.ts +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.test.ts @@ -98,6 +98,7 @@ describe('metric_suggestions', () => { ).map((table) => expect(getSuggestions({ table, keptLayerIds: ['l1'] })).toEqual([])) ); }); + test('does not suggest for a static value', () => { const suggestion = getSuggestions({ table: { @@ -133,6 +134,29 @@ describe('metric_suggestions', () => { expect(suggestion).toHaveLength(0); }); + + test('does not suggest for text based languages', () => { + const col = { + columnId: 'id', + operation: { + dataType: 'number', + label: `Top values`, + isBucketed: false, + }, + } as const; + const suggestion = getSuggestions({ + table: { + columns: [col], + isMultiRow: false, + layerId: 'l1', + changeType: 'unchanged', + }, + keptLayerIds: [], + datasourceId: 'textBased', + }); + + expect(suggestion).toHaveLength(0); + }); test('suggests a basic metric chart', () => { const [suggestion, ...rest] = getSuggestions({ table: { diff --git a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts index c48e463ec83d..7e00322fedcd 100644 --- a/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/legacy_metric/metric_suggestions.ts @@ -20,6 +20,7 @@ export function getSuggestions({ table, state, keptLayerIds, + datasourceId, }: SuggestionRequest): Array> { // We only render metric charts for single-row queries. We require a single, numeric column. if ( @@ -39,6 +40,11 @@ export function getSuggestions({ return []; } + // do not return the legacy metric vis for the textbased mode (i.e. ES|QL) + if (datasourceId === 'textBased') { + return []; + } + return [getSuggestion(table)]; } diff --git a/x-pack/plugins/lens/tsconfig.json b/x-pack/plugins/lens/tsconfig.json index 6cb071d18352..8af19f218fee 100644 --- a/x-pack/plugins/lens/tsconfig.json +++ b/x-pack/plugins/lens/tsconfig.json @@ -90,9 +90,11 @@ "@kbn/search-response-warnings", "@kbn/logging", "@kbn/core-plugins-server", + "@kbn/text-based-languages", "@kbn/field-utils", - "@kbn/shared-ux-button-toolbar", - "@kbn/cell-actions" + "@kbn/discover-utils", + "@kbn/cell-actions", + "@kbn/shared-ux-button-toolbar" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/licensing/public/plugin.test.ts b/x-pack/plugins/licensing/public/plugin.test.ts index 9804f1ba8e1b..5c571d0c6a40 100644 --- a/x-pack/plugins/licensing/public/plugin.test.ts +++ b/x-pack/plugins/licensing/public/plugin.test.ts @@ -16,7 +16,6 @@ import { License } from '../common/license'; import { licenseMock } from '../common/licensing.mock'; import { coreMock } from '@kbn/core/public/mocks'; import { HttpInterceptor } from '@kbn/core/public'; -import type { AnalyticsServiceSetup } from '@kbn/core-analytics-browser'; const coreStart = coreMock.createStart(); describe('licensing plugin', () => { @@ -443,69 +442,5 @@ describe('licensing plugin', () => { expect(removeInterceptorMock).toHaveBeenCalledTimes(1); }); - - it('registers the subscription upsell events', async () => { - const sessionStorage = coreMock.createStorage(); - plugin = new LicensingPlugin(coreMock.createPluginInitializerContext(), sessionStorage); - - const coreSetup = coreMock.createSetup(); - - await plugin.setup(coreSetup); - await plugin.stop(); - - expect(findRegisteredEventTypeByName('subscription__upsell__click', coreSetup.analytics)) - .toMatchInlineSnapshot(` - Array [ - Object { - "eventType": "subscription__upsell__click", - "schema": Object { - "feature": Object { - "_meta": Object { - "description": "A human-readable identifier describing the feature that is being promoted", - }, - "type": "keyword", - }, - "source": Object { - "_meta": Object { - "description": "A human-readable identifier describing the location of the beginning of the subscription flow", - }, - "type": "keyword", - }, - }, - }, - ] - `); - expect(findRegisteredEventTypeByName('subscription__upsell__impression', coreSetup.analytics)) - .toMatchInlineSnapshot(` - Array [ - Object { - "eventType": "subscription__upsell__impression", - "schema": Object { - "feature": Object { - "_meta": Object { - "description": "A human-readable identifier describing the feature that is being promoted", - }, - "type": "keyword", - }, - "source": Object { - "_meta": Object { - "description": "A human-readable identifier describing the location of the beginning of the subscription flow", - }, - "type": "keyword", - }, - }, - }, - ] - `); - }); }); }); - -function findRegisteredEventTypeByName( - eventTypeName: string, - analyticsClientMock: jest.Mocked -) { - return analyticsClientMock.registerEventType.mock.calls.find( - ([{ eventType }]) => eventType === eventTypeName - )!; -} diff --git a/x-pack/plugins/licensing/public/plugin.ts b/x-pack/plugins/licensing/public/plugin.ts index bc350675d7dd..3953a29a0821 100644 --- a/x-pack/plugins/licensing/public/plugin.ts +++ b/x-pack/plugins/licensing/public/plugin.ts @@ -8,7 +8,6 @@ import { Observable, Subject, Subscription } from 'rxjs'; import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; -import { registerEvents as registerSubscriptionTrackingEvents } from '@kbn/subscription-tracking'; import { ILicense } from '../common/types'; import { LicensingPluginSetup, LicensingPluginStart } from './types'; import { createLicenseUpdate } from '../common/license_update'; @@ -85,7 +84,6 @@ export class LicensingPlugin implements Plugin { if (license.isAvailable) { diff --git a/x-pack/plugins/licensing/tsconfig.json b/x-pack/plugins/licensing/tsconfig.json index 1deb735f9946..804bf057afa6 100644 --- a/x-pack/plugins/licensing/tsconfig.json +++ b/x-pack/plugins/licensing/tsconfig.json @@ -14,8 +14,6 @@ "@kbn/std", "@kbn/i18n", "@kbn/analytics-client", - "@kbn/subscription-tracking", - "@kbn/core-analytics-browser", "@kbn/logging-mocks" ], "exclude": ["target/**/*"] diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx index 7edcf5b53f72..5c2bfb904568 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/entry_renderer.test.tsx @@ -20,7 +20,7 @@ import { isOperator, matchesOperator, } from '@kbn/securitysolution-list-utils'; -import { validateFilePathInput } from '@kbn/securitysolution-utils'; +import { validatePotentialWildcardInput } from '@kbn/securitysolution-utils'; import { useFindListsBySize } from '@kbn/securitysolution-list-hooks'; import type { FieldSpec } from '@kbn/data-plugin/common'; import { fields, getField } from '@kbn/data-plugin/common/mocks'; @@ -1050,7 +1050,7 @@ describe('BuilderEntryItem', () => { test('it invokes "setWarningsExist" when invalid value in field value input', async () => { const mockSetWarningsExists = jest.fn(); - (validateFilePathInput as jest.Mock).mockReturnValue('some warning message'); + (validatePotentialWildcardInput as jest.Mock).mockReturnValue('some warning message'); wrapper = mount( { test('it does not invoke "setWarningsExist" when valid value in field value input', async () => { const mockSetWarningsExists = jest.fn(); - (validateFilePathInput as jest.Mock).mockReturnValue(undefined); + (validatePotentialWildcardInput as jest.Mock).mockReturnValue(undefined); wrapper = mount( = ({ const renderOperatorInput = (isFirst: boolean): JSX.Element => { // for event filters forms - // show extra operators for wildcards when field is `file.path.text` - const isFilePathTextField = entry.field !== undefined && entry.field.name === 'file.path.text'; + // show extra operators for wildcards when field supports matches + const doesFieldSupportMatches = entry.field !== undefined && fieldSupportsMatches(entry.field); const isEventFilterList = listType === 'endpoint_events'; const augmentedOperatorsList = - operatorsList && isFilePathTextField && isEventFilterList + operatorsList && doesFieldSupportMatches && isEventFilterList ? operatorsList : operatorsList?.filter((operator) => operator.type !== OperatorTypeEnum.WILDCARD); @@ -358,8 +359,8 @@ export const BuilderEntryItem: React.FC = ({ } }; - // show this when wildcard filename with matches operator - const getWildcardWarning = (precedingWarning: string): React.ReactNode => { + // show this when wildcard with matches operator + const getWildcardWarningInfo = (precedingWarning: string): React.ReactNode => { return (

    {precedingWarning}{' '} @@ -368,7 +369,7 @@ export const BuilderEntryItem: React.FC = ({ content={ } size="m" @@ -430,11 +431,13 @@ export const BuilderEntryItem: React.FC = ({ if (osTypes) { [os] = osTypes as OperatingSystem[]; } - const warning = validateFilePathInput({ os, value: wildcardValue }); + const warning = validatePotentialWildcardInput({ + field: entry.field?.name, + os, + value: wildcardValue, + }); actualWarning = - warning === FILENAME_WILDCARD_WARNING - ? warning && getWildcardWarning(warning) - : warning; + warning === WILDCARD_WARNING ? warning && getWildcardWarningInfo(warning) : warning; } return ( diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts index 3cc350629ff9..ef3982166e19 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts +++ b/x-pack/plugins/lists/public/exceptions/components/builder/helpers.test.ts @@ -212,7 +212,7 @@ describe('Exception builder helpers', () => { expect(output).toEqual(expected); }); - test('it returns all fields unfiletered if "item.nested" is not "child" or "parent"', () => { + test('it returns all fields unfiltered if "item.nested" is not "child" or "parent"', () => { const payloadIndexPattern = getMockIndexPattern(); const payloadItem: FormattedBuilderEntry = getMockBuilderEntry(); const output = getFilteredIndexPatterns(payloadIndexPattern, payloadItem); diff --git a/x-pack/plugins/log_explorer/public/components/flyout_detail/flyout_highlights.tsx b/x-pack/plugins/log_explorer/public/components/flyout_detail/flyout_highlights.tsx index 74d65d73f23b..e74ee0a4b813 100644 --- a/x-pack/plugins/log_explorer/public/components/flyout_detail/flyout_highlights.tsx +++ b/x-pack/plugins/log_explorer/public/components/flyout_detail/flyout_highlights.tsx @@ -7,7 +7,10 @@ import React from 'react'; import { FlyoutContentActions } from '@kbn/discover-plugin/public'; import { DataTableRecord } from '@kbn/discover-utils/src/types'; +import { AgentIcon, CloudProvider, CloudProviderIcon } from '@kbn/custom-icons'; import { useMeasure } from 'react-use/lib'; +import { AgentName } from '@kbn/elastic-agent-utils'; +import { first } from 'lodash'; import { FlyoutDoc } from './types'; import * as constants from '../../../common/constants'; import { HighlightField } from './sub_components/highlight_field'; @@ -47,156 +50,170 @@ export function FlyoutHighlights({ }) { const [ref, dimensions] = useMeasure(); const { columns, fieldWidth } = useFlyoutColumnWidth(dimensions.width); + return ( + {/* Service highlight */} {formattedDoc[constants.SERVICE_NAME_FIELD] && ( + } + label={flyoutServiceLabel} + value={flattenedDoc[constants.SERVICE_NAME_FIELD]} width={fieldWidth} /> )} {formattedDoc[constants.TRACE_ID_FIELD] && ( )} - + {/* Infrastructure highlight */} {formattedDoc[constants.HOST_NAME_FIELD] && ( )} {formattedDoc[constants.ORCHESTRATOR_CLUSTER_NAME_FIELD] && ( )} {formattedDoc[constants.ORCHESTRATOR_RESOURCE_ID_FIELD] && ( )} - + {/* Cloud highlight */} {formattedDoc[constants.CLOUD_PROVIDER_FIELD] && ( + } + label={flyoutCloudProviderLabel} + value={flattenedDoc[constants.CLOUD_PROVIDER_FIELD]} width={fieldWidth} /> )} {formattedDoc[constants.CLOUD_REGION_FIELD] && ( )} {formattedDoc[constants.CLOUD_AVAILABILITY_ZONE_FIELD] && ( )} {formattedDoc[constants.CLOUD_PROJECT_ID_FIELD] && ( )} {formattedDoc[constants.CLOUD_INSTANCE_ID_FIELD] && ( )} - + {/* Other highlights */} {formattedDoc[constants.LOG_FILE_PATH_FIELD] && ( )} {formattedDoc[constants.DATASTREAM_NAMESPACE_FIELD] && ( )} {formattedDoc[constants.DATASTREAM_DATASET_FIELD] && ( )} {formattedDoc[constants.AGENT_NAME_FIELD] && ( )} diff --git a/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/highlight_field.tsx b/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/highlight_field.tsx index ca47b1054823..1034a3015cc8 100644 --- a/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/highlight_field.tsx +++ b/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/highlight_field.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiFlexGroup, EuiFlexItem, EuiText, copyToClipboard } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiText, copyToClipboard, EuiTextTruncate } from '@elastic/eui'; import React, { ReactNode, useMemo, useState } from 'react'; import { HoverAction, HoverActionType } from './hover_action'; import { @@ -18,21 +18,22 @@ import { import { useDiscoverActionsContext } from '../../../hooks/use_discover_action'; interface HighlightFieldProps { - label: string | ReactNode; field: string; - value: unknown; formattedValue: string; - dataTestSubj: string; + icon?: ReactNode; + label: string | ReactNode; + value: unknown; width: number; } export function HighlightField({ - label, field, - value, formattedValue, - dataTestSubj, + icon, + label, + value, width, + ...props }: HighlightFieldProps) { const filterForText = flyoutHoverActionFilterForText(value); const filterOutText = flyoutHoverActionFilterOutText(value); @@ -89,14 +90,33 @@ export function HighlightField({ [filterForText, filterOutText, actions, field, value, columnAdded] ); return formattedValue ? ( - + {label} - + + + {icon && {icon}} + + + {(truncatedText: string) => ( + + )} + + + + ) : null; diff --git a/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/hover_action.tsx b/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/hover_action.tsx index 5ed25be2b36d..1b5883ed082e 100644 --- a/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/hover_action.tsx +++ b/x-pack/plugins/log_explorer/public/components/flyout_detail/sub_components/hover_action.tsx @@ -7,14 +7,7 @@ import React from 'react'; -import { - EuiFlexGroup, - EuiToolTip, - EuiButtonIcon, - useEuiTheme, - EuiTextTruncate, - EuiText, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiToolTip, EuiButtonIcon, useEuiTheme, EuiFlexItem } from '@elastic/eui'; import type { IconType } from '@elastic/eui'; export interface HoverActionType { @@ -26,12 +19,11 @@ export interface HoverActionType { } interface HoverActionProps { - displayText: string; + children: React.ReactNode; actions: HoverActionType[]; - width: number; } -export const HoverAction = ({ displayText, actions, width }: HoverActionProps) => { +export const HoverAction = ({ children, actions }: HoverActionProps) => { const { euiTheme } = useEuiTheme(); return ( @@ -49,14 +41,7 @@ export const HoverAction = ({ displayText, actions, width }: HoverActionProps) = }, }} > - - {(truncatedText: string) => ( - - )} - + {children} { {aiAssistant.isEnabled() && explainLogMessageMessages ? ( - + ) : null} {aiAssistant.isEnabled() && similarLogMessageMessages ? ( - + ) : null} diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts index 7e23353460df..105b17dcd5a2 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts @@ -27,6 +27,13 @@ import { LICENSED_FEATURES } from '../../../licensed_features'; jest.mock('../../../kibana_services'); export class MockSearchSource { + getField(fieldName: string) { + if (fieldName === 'filter') { + return []; + } + + throw new Error(`Unsupported search source field: ${fieldName}`); + } setField = jest.fn(); setParent() {} getSearchRequestBody() { @@ -324,7 +331,7 @@ describe('ESGeoGridSource', () => { index: 'foo-*', renderAs: 'heatmap', requestBody: - "(fields:('0':('0':index,'1':(fields:())),'1':('0':size,'1':0),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:())),'5':('0':query,'1':(language:KQL,query:'')),'6':('0':aggs,'1':())))", + "(fields:('0':('0':index,'1':(fields:())),'1':('0':size,'1':0),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:())),'5':('0':query,'1':(language:KQL,query:'')),'6':('0':aggs,'1':()),'7':('0':filter,'1':!((meta:(),query:(exists:(field:bar)))))))", token: '1234', }); }); diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx index 4acb400807ad..703ab4f45b96 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx @@ -21,6 +21,7 @@ import { DataView } from '@kbn/data-plugin/common'; import { Adapters } from '@kbn/inspector-plugin/common/adapters'; import { ACTION_GLOBAL_APPLY_FILTER } from '@kbn/unified-search-plugin/public'; import { getTileUrlParams } from '@kbn/maps-vector-tile-utils'; +import { type Filter, buildExistsFilter } from '@kbn/es-query'; import { makeESBbox } from '../../../../common/elasticsearch_util'; import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson'; import { UpdateSourceEditor } from './update_source_editor'; @@ -553,6 +554,11 @@ export class ESGeoGridSource extends AbstractESAggSource implements IMvtVectorSo const dataView = await this.getIndexPattern(); const searchSource = await this.makeSearchSource(requestMeta, 0); searchSource.setField('aggs', this.getValueAggsDsl(dataView)); + // Filter out documents without geo fields for broad index-pattern support + searchSource.setField('filter', [ + ...(searchSource.getField('filter') as Filter[]), + buildExistsFilter({ name: this._descriptor.geoField, type: 'geo_point' }, dataView), + ]); const mvtUrlServicePath = getHttp().basePath.prepend( `${MVT_GETGRIDTILE_API_PATH}/{z}/{x}/{y}.pbf` diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index 7f7fde393de9..3585150459b8 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -53,6 +53,13 @@ describe('ESSearchSource', () => { beforeEach(async () => { const mockSearchSource = { + getField: (fieldName: string) => { + if (fieldName === 'filter') { + return []; + } + + throw new Error(`Unsupported search source field: ${fieldName}`); + }, setField: jest.fn(), getSearchRequestBody() { return { @@ -131,7 +138,7 @@ describe('ESSearchSource', () => { hasLabels: 'false', index: 'foobar-title-*', requestBody: - "(fields:('0':('0':index,'1':(fields:(),title:'foobar-title-*')),'1':('0':size,'1':1000),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:(),title:'foobar-title-*')),'5':('0':query,'1':(language:KQL,query:'tooltipField: foobar')),'6':('0':fieldsFromSource,'1':!(_id)),'7':('0':source,'1':!f),'8':('0':fields,'1':!(tooltipField,styleField))))", + "(fields:('0':('0':index,'1':(fields:(),title:'foobar-title-*')),'1':('0':size,'1':1000),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:(),title:'foobar-title-*')),'5':('0':query,'1':(language:KQL,query:'tooltipField: foobar')),'6':('0':fieldsFromSource,'1':!(_id)),'7':('0':source,'1':!f),'8':('0':fields,'1':!(tooltipField,styleField)),'9':('0':filter,'1':!((meta:(),query:(exists:(field:bar)))))))", token: '1234', }); }); diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 77f4b684caf1..5d0f6aa59c55 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import type { SearchResponseWarning } from '@kbn/search-response-warnings'; import { GeoJsonProperties, Geometry, Position } from 'geojson'; import type { KibanaExecutionContext } from '@kbn/core/public'; -import { type Filter, buildPhraseFilter, type TimeRange } from '@kbn/es-query'; +import { type Filter, buildExistsFilter, buildPhraseFilter, type TimeRange } from '@kbn/es-query'; import type { DataViewField, DataView } from '@kbn/data-plugin/common'; import { lastValueFrom } from 'rxjs'; import { Adapters } from '@kbn/inspector-plugin/common/adapters'; @@ -923,6 +923,12 @@ export class ESSearchSource extends AbstractESSource implements IMvtVectorSource }) ); + // Filter out documents without geo fields to avoid shard failures for indices without geo fields + searchSource.setField('filter', [ + ...(searchSource.getField('filter') as Filter[]), + buildExistsFilter({ name: this._descriptor.geoField, type: 'geo_point' }, dataView), + ]); + const mvtUrlServicePath = getHttp().basePath.prepend(`${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf`); const tileUrlParams = getTileUrlParams({ diff --git a/x-pack/plugins/maps/public/maps_vis_type_alias.ts b/x-pack/plugins/maps/public/maps_vis_type_alias.ts index bcbf0170afb2..e16168964361 100644 --- a/x-pack/plugins/maps/public/maps_vis_type_alias.ts +++ b/x-pack/plugins/maps/public/maps_vis_type_alias.ts @@ -24,8 +24,10 @@ export function getMapsVisTypeAlias() { }); return { - aliasApp: APP_ID, - aliasPath: `/${MAP_PATH}`, + alias: { + app: APP_ID, + path: `/${MAP_PATH}`, + }, name: APP_ID, title: APP_NAME, description: appDescription, @@ -45,8 +47,10 @@ export function getMapsVisTypeAlias() { title, description, updatedAt, - editUrl: getEditPath(id), - editApp: APP_ID, + editor: { + editUrl: getEditPath(id), + editApp: APP_ID, + }, icon: APP_ICON, stage: 'production' as VisualizationStage, savedObjectType: type, diff --git a/x-pack/plugins/ml/common/constants/locator.ts b/x-pack/plugins/ml/common/constants/locator.ts index 92c89c5aedf9..614c037c1302 100644 --- a/x-pack/plugins/ml/common/constants/locator.ts +++ b/x-pack/plugins/ml/common/constants/locator.ts @@ -55,6 +55,7 @@ export const ML_PAGES = { ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: 'jobs/new_job/step/job_type', ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: 'jobs/new_job/step/index_or_search', ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: 'jobs/new_job/from_lens', + ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS: 'jobs/new_job/from_pattern_analysis', ANOMALY_DETECTION_CREATE_JOB_FROM_MAP: 'jobs/new_job/from_map', ANOMALY_DETECTION_MODULES_VIEW_OR_CREATE: 'modules/check_view_or_create', SETTINGS: 'settings', diff --git a/x-pack/plugins/ml/common/constants/new_job.ts b/x-pack/plugins/ml/common/constants/new_job.ts index 24584a6e8d29..676182d0ac16 100644 --- a/x-pack/plugins/ml/common/constants/new_job.ts +++ b/x-pack/plugins/ml/common/constants/new_job.ts @@ -26,6 +26,7 @@ export enum CREATED_BY_LABEL { APM_TRANSACTION = 'ml-module-apm-transaction', SINGLE_METRIC_FROM_LENS = 'single-metric-wizard-from-lens', MULTI_METRIC_FROM_LENS = 'multi-metric-wizard-from-lens', + CATEGORIZATION_FROM_PATTERN_ANALYSIS = 'categorization-wizard-from-pattern-analysis', } export const DEFAULT_MODEL_MEMORY_LIMIT = '10MB'; diff --git a/x-pack/plugins/ml/common/openapi/ml_apis.yaml b/x-pack/plugins/ml/common/openapi/ml_apis.yaml index 5b7a68309c94..9f2a7de49818 100644 --- a/x-pack/plugins/ml/common/openapi/ml_apis.yaml +++ b/x-pack/plugins/ml/common/openapi/ml_apis.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Machine learning APIs description: Kibana APIs for the machine learning feature - version: "1.0.1" + version: "1.0.2" license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license @@ -82,7 +82,8 @@ components: required: false schema: type: boolean - example: 'true' + examples: + - true securitySchemes: basicAuth: type: http @@ -187,12 +188,14 @@ components: properties: error: type: string - example: Unauthorized + examples: + - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 examples: mlSyncExample: summary: Two anomaly detection jobs required synchronization in this example. diff --git a/x-pack/plugins/ml/common/openapi/ml_apis_serverless.yaml b/x-pack/plugins/ml/common/openapi/ml_apis_serverless.yaml index 649bc3db06ac..6ff44e29517e 100644 --- a/x-pack/plugins/ml/common/openapi/ml_apis_serverless.yaml +++ b/x-pack/plugins/ml/common/openapi/ml_apis_serverless.yaml @@ -1,8 +1,8 @@ -openapi: 3.0.1 +openapi: 3.1.0 info: title: Machine learning APIs description: Kibana APIs for the machine learning feature - version: "1.0.1" + version: "1.0.2" license: name: Elastic License 2.0 url: https://www.elastic.co/licensing/elastic-license @@ -46,7 +46,8 @@ components: required: false schema: type: boolean - example: 'true' + examples: + - true securitySchemes: apiKeyAuth: type: apiKey @@ -148,12 +149,14 @@ components: properties: error: type: string - example: Unauthorized + examples: + - Unauthorized message: type: string statusCode: type: integer - example: 401 + examples: + - 401 examples: mlSyncExample: summary: Two anomaly detection jobs required synchronization in this example. diff --git a/x-pack/plugins/ml/common/types/locator.ts b/x-pack/plugins/ml/common/types/locator.ts index 329ba59ba907..85b2550eb8e3 100644 --- a/x-pack/plugins/ml/common/types/locator.ts +++ b/x-pack/plugins/ml/common/types/locator.ts @@ -49,6 +49,7 @@ export type MlGenericUrlState = MLPageState< | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_LENS | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_MAP + | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE | typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX | typeof ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB diff --git a/x-pack/plugins/ml/common/types/trained_models.ts b/x-pack/plugins/ml/common/types/trained_models.ts index 70f588712c35..95815cd3b87a 100644 --- a/x-pack/plugins/ml/common/types/trained_models.ts +++ b/x-pack/plugins/ml/common/types/trained_models.ts @@ -98,6 +98,7 @@ export type TrainedModelConfigResponse = estypes.MlTrainedModelConfig & { * Associated pipelines. Extends response from the ES endpoint. */ pipelines?: Record | null; + origin_job_exists?: boolean; metadata?: { analytics_config: DataFrameAnalyticsConfig; diff --git a/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx b/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx index 3919f9f9e5cc..70c3be96c667 100644 --- a/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx +++ b/x-pack/plugins/ml/public/application/aiops/change_point_detection.tsx @@ -65,6 +65,7 @@ export const ChangePointDetectionPage: FC = () => { 'share', 'storage', 'theme', + 'uiActions', 'uiSettings', 'unifiedSearch', 'usageCollection', diff --git a/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx b/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx index 455ff9bfc137..187843505cef 100644 --- a/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx +++ b/x-pack/plugins/ml/public/application/aiops/log_categorization.tsx @@ -56,6 +56,7 @@ export const LogCategorizationPage: FC = () => { 'share', 'storage', 'theme', + 'uiActions', 'uiSettings', 'unifiedSearch', ])} diff --git a/x-pack/plugins/ml/public/application/aiops/log_rate_analysis.tsx b/x-pack/plugins/ml/public/application/aiops/log_rate_analysis.tsx index c20264a129ea..4c2c1dfd637d 100644 --- a/x-pack/plugins/ml/public/application/aiops/log_rate_analysis.tsx +++ b/x-pack/plugins/ml/public/application/aiops/log_rate_analysis.tsx @@ -59,6 +59,7 @@ export const LogRateAnalysisPage: FC = () => { 'share', 'storage', 'theme', + 'uiActions', 'uiSettings', 'unifiedSearch', ])} diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/anomaly_details.tsx b/x-pack/plugins/ml/public/application/components/anomalies_table/anomaly_details.tsx index 556dd5c810d8..eb5450d0d61b 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/anomaly_details.tsx +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/anomaly_details.tsx @@ -361,7 +361,7 @@ const CategoryExamples: FC<{ definition: CategoryDefinition; examples: string[] {definition !== undefined && definition.terms && ( diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx index e617d05f94d3..aecbb0aa0108 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix.tsx @@ -101,7 +101,7 @@ export interface ScatterplotMatrixProps { legendType?: LegendType; searchQuery?: estypes.QueryDslQueryContainer; runtimeMappings?: RuntimeMappings; - indexPattern?: DataView; + dataView?: DataView; query?: Query; } @@ -113,7 +113,7 @@ export const ScatterplotMatrix: FC = ({ legendType, searchQuery, runtimeMappings, - indexPattern, + dataView, query, }) => { const { esSearch } = useMlApiContext(); @@ -210,9 +210,7 @@ export const ScatterplotMatrix: FC = ({ vegaSpec.data = { url: { '%context%': true, - ...(indexPattern?.timeFieldName - ? { ['%timefield%']: `${indexPattern?.timeFieldName}` } - : {}), + ...(dataView?.timeFieldName ? { ['%timefield%']: `${dataView?.timeFieldName}` } : {}), index, body: { fields: fieldsToFetch, @@ -300,7 +298,7 @@ export const ScatterplotMatrix: FC = ({ } const combinedRuntimeMappings = - indexPattern && getCombinedRuntimeMappings(indexPattern, runtimeMappings); + dataView && getCombinedRuntimeMappings(dataView, runtimeMappings); const body = { fields: queryFields, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts index 6cd5c40d66e4..139b49f7c2b4 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/use_results_view_config.ts @@ -37,12 +37,10 @@ export const useResultsViewConfig = (jobId: string) => { } = useMlKibana(); const trainedModelsApiService = useTrainedModelsApiService(); - const [indexPattern, setIndexPattern] = useState(undefined); - const [indexPatternErrorMessage, setIndexPatternErrorMessage] = useState( - undefined - ); + const [dataView, setDataView] = useState(undefined); + const [dataViewErrorMessage, setDataViewErrorMessage] = useState(undefined); const [isInitialized, setIsInitialized] = useState(false); - const [needsDestIndexPattern, setNeedsDestIndexPattern] = useState(false); + const [needsDestDataView, setNeedsDestDataView] = useState(false); const [isLoadingJobConfig, setIsLoadingJobConfig] = useState(false); const [jobConfig, setJobConfig] = useState(undefined); const [jobCapsServiceErrorMessage, setJobCapsServiceErrorMessage] = useState( @@ -100,39 +98,39 @@ export const useResultsViewConfig = (jobId: string) => { try { const destIndex = getDestinationIndex(jobConfigUpdate); const destDataViewId = (await getDataViewIdFromName(destIndex)) ?? destIndex; - let dataView: DataView | undefined; + let fetchedDataView: DataView | undefined; try { - dataView = await dataViews.get(destDataViewId); + fetchedDataView = await dataViews.get(destDataViewId); // Force refreshing the fields list here because a user directly coming // from the job creation wizard might land on the page without the // data view being fully initialized because it was created // before the analytics job populated the destination index. - await dataViews.refreshFields(dataView); + await dataViews.refreshFields(fetchedDataView); } catch (e) { - dataView = undefined; + fetchedDataView = undefined; } - if (dataView === undefined) { - setNeedsDestIndexPattern(true); + if (fetchedDataView === undefined) { + setNeedsDestDataView(true); const sourceIndex = jobConfigUpdate.source.index[0]; const sourceDataViewId = (await getDataViewIdFromName(sourceIndex)) ?? sourceIndex; try { - dataView = await dataViews.get(sourceDataViewId); + fetchedDataView = await dataViews.get(sourceDataViewId); } catch (e) { - dataView = undefined; + fetchedDataView = undefined; } } - if (dataView !== undefined) { - await newJobCapsServiceAnalytics.initializeFromDataVIew(dataView); + if (fetchedDataView !== undefined) { + await newJobCapsServiceAnalytics.initializeFromDataVIew(fetchedDataView); setJobConfig(analyticsConfigs.data_frame_analytics[0]); - setIndexPattern(dataView); + setDataView(fetchedDataView); setIsInitialized(true); setIsLoadingJobConfig(false); } else { - setIndexPatternErrorMessage( + setDataViewErrorMessage( i18n.translate('xpack.ml.dataframe.analytics.results.dataViewMissingErrorMessage', { defaultMessage: 'To view this page, a Kibana data view is necessary for either the destination or source index of this analytics job.', @@ -153,15 +151,15 @@ export const useResultsViewConfig = (jobId: string) => { }, []); return { - indexPattern, - indexPatternErrorMessage, + dataView, + dataViewErrorMessage, isInitialized, isLoadingJobConfig, jobCapsServiceErrorMessage, jobConfig, jobConfigErrorMessage, jobStatus, - needsDestIndexPattern, + needsDestDataView, totalFeatureImportance, }; }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx index c574a6f66108..d065ef84fa97 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -356,9 +356,9 @@ export const ConfigurationStepForm: FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const indexPatternFieldsTableItems = useMemo(() => { - if (indexData?.indexPatternFields !== undefined) { - return indexData.indexPatternFields.map((field) => ({ + const dataViewFieldsTableItems = useMemo(() => { + if (indexData?.dataViewFields !== undefined) { + return indexData.dataViewFields.map((field) => ({ name: field, is_included: false, is_required: false, @@ -366,7 +366,7 @@ export const ConfigurationStepForm: FC = ({ } return []; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [`${indexData?.indexPatternFields}`]); + }, [`${indexData?.dataViewFields}`]); useEffect(() => { if (typeof savedSearchQueryStr === 'string') { @@ -377,11 +377,11 @@ export const ConfigurationStepForm: FC = ({ useEffect(() => { if (isJobTypeWithDepVar) { - const indexPatternRuntimeFields = getCombinedRuntimeMappings(selectedDataView); + const dataViewRuntimeFields = getCombinedRuntimeMappings(selectedDataView); let runtimeOptions; - if (indexPatternRuntimeFields) { - runtimeOptions = getRuntimeDepVarOptions(jobType, indexPatternRuntimeFields); + if (dataViewRuntimeFields) { + runtimeOptions = getRuntimeDepVarOptions(jobType, dataViewRuntimeFields); } loadDepVarOptions(form, runtimeOptions); @@ -527,7 +527,7 @@ export const ConfigurationStepForm: FC = ({ legendType: getScatterplotMatrixLegendType(jobType), searchQuery: jobConfigQuery, runtimeMappings, - indexPattern: selectedDataView, + dataView: selectedDataView, }), // eslint-disable-next-line react-hooks/exhaustive-deps [ @@ -571,7 +571,7 @@ export const ConfigurationStepForm: FC = ({ const tableItems = includesTableItems.length > 0 && !noDocsContainMappedFields ? includesTableItems - : indexPatternFieldsTableItems; + : dataViewFieldsTableItems; return ( = ({ fullWidth > diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx index c32530658e6f..bf5e43a8f72a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/create_step/create_step.tsx @@ -42,13 +42,8 @@ export const CreateStep: FC = ({ actions, state, step }) => { const { createAnalyticsJob, setFormState, startAnalyticsJob } = actions; const { isAdvancedEditorValidJson, isJobCreated, isJobStarted, isValid, requestMessages } = state; - const { - createIndexPattern, - destinationIndex, - destinationIndexPatternTitleExists, - jobId, - jobType, - } = state.form; + const { createDataView, destinationIndex, destinationDataViewTitleExists, jobId, jobType } = + state.form; const [startChecked, setStartChecked] = useState(true); const [creationTriggered, setCreationTriggered] = useState(false); @@ -56,7 +51,7 @@ export const CreateStep: FC = ({ actions, state, step }) => { useEffect(() => { if (canCreateDataView === false) { - setFormState({ createIndexPattern: false }); + setFormState({ createDataView: false }); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [capabilities]); @@ -106,7 +101,7 @@ export const CreateStep: FC = ({ actions, state, step }) => { onChange={(e) => { setStartChecked(e.target.checked); if (e.target.checked === false) { - setFormState({ createIndexPattern: false }); + setFormState({ createDataView: false }); } }} /> @@ -117,8 +112,8 @@ export const CreateStep: FC = ({ actions, state, step }) => { = ({ actions, state, step }) => { , ] : []), - ...(createIndexPattern && destinationIndexPatternTitleExists + ...(createDataView && destinationDataViewTitleExists ? [ i18n.translate( 'xpack.ml.dataframe.analytics.create.dataViewExistsError', @@ -146,7 +141,7 @@ export const CreateStep: FC = ({ actions, state, step }) => { ), ] : []), - ...(!createIndexPattern && !destinationIndexPatternTitleExists + ...(!createDataView && !destinationDataViewTitleExists ? [ {i18n.translate( @@ -163,7 +158,7 @@ export const CreateStep: FC = ({ actions, state, step }) => { > = ({ actions, state, step }) => { defaultMessage: 'Create data view', } )} - checked={createIndexPattern === true} - onChange={() => setFormState({ createIndexPattern: !createIndexPattern })} - data-test-subj="mlAnalyticsCreateJobWizardCreateIndexPatternCheckbox" + checked={createDataView === true} + onChange={() => setFormState({ createDataView: !createDataView })} + data-test-subj="mlAnalyticsCreateJobWizardCreateDataViewCheckbox" /> @@ -186,7 +181,7 @@ export const CreateStep: FC = ({ actions, state, step }) => { disabled={ !isValid || !isAdvancedEditorValidJson || - (destinationIndexPatternTitleExists === true && createIndexPattern === true) + (destinationDataViewTitleExists === true && createDataView === true) } onClick={handleCreation} fill diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index cf3c0fcf05ef..2336113f917d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -25,7 +25,7 @@ import { getFieldType, getDataGridSchemaFromKibanaFieldType, getDataGridSchemaFromESFieldType, - getFieldsFromKibanaIndexPattern, + getFieldsFromKibanaDataView, showDataGridColumnChartErrorMessageToast, useDataGrid, useRenderCellValue, @@ -58,8 +58,8 @@ function getRuntimeFieldColumns(runtimeMappings: RuntimeMappings) { }); } -function getIndexPatternColumns(indexPattern: DataView, fieldsFilter: string[]) { - const { fields } = indexPattern; +function getDataViewColumns(dataView: DataView, fieldsFilter: string[]) { + const { fields } = dataView; return fields .filter((field) => fieldsFilter.includes(field.name)) @@ -78,7 +78,7 @@ function getIndexPatternColumns(indexPattern: DataView, fieldsFilter: string[]) } export const useIndexData = ( - indexPattern: DataView, + dataView: DataView, query: Record | undefined, toastNotifications: CoreSetup['notifications']['toasts'], runtimeMappings?: RuntimeMappings @@ -87,7 +87,7 @@ export const useIndexData = ( // This is a workaround to avoid passing potentially thousands of unpopulated fields // (for example, as part of filebeat/metricbeat/ECS based indices) // to the data grid component which would significantly slow down the page. - const [indexPatternFields, setIndexPatternFields] = useState(); + const [dataViewFields, setDataViewFields] = useState(); const [timeRangeMs, setTimeRangeMs] = useState(); useEffect(() => { @@ -96,7 +96,7 @@ export const useIndexData = ( setStatus(INDEX_STATUS.LOADING); const esSearchRequest = { - index: indexPattern.title, + index: dataView.title, body: { fields: ['*'], _source: false, @@ -116,13 +116,13 @@ export const useIndexData = ( // Get all field names for each returned doc and flatten it // to a list of unique field names used across all docs. - const allDataViewFields = getFieldsFromKibanaIndexPattern(indexPattern); + const allDataViewFields = getFieldsFromKibanaDataView(dataView); const populatedFields = [...new Set(docs.map(Object.keys).flat(1))] .filter((d) => allDataViewFields.includes(d)) .sort(); setStatus(INDEX_STATUS.LOADED); - setIndexPatternFields(populatedFields); + setDataViewFields(populatedFields); } catch (e) { setErrorMessage(extractErrorMessage(e)); setStatus(INDEX_STATUS.ERROR); @@ -136,20 +136,20 @@ export const useIndexData = ( // To be used for data grid column selection // and will be applied to doc and chart queries. const combinedRuntimeMappings = useMemo( - () => getCombinedRuntimeMappings(indexPattern, runtimeMappings), - [indexPattern, runtimeMappings] + () => getCombinedRuntimeMappings(dataView, runtimeMappings), + [dataView, runtimeMappings] ); // Available data grid columns, will be a combination of index pattern and runtime fields. const [columns, setColumns] = useState([]); useEffect(() => { - if (Array.isArray(indexPatternFields)) { + if (Array.isArray(dataViewFields)) { setColumns([ - ...getIndexPatternColumns(indexPattern, indexPatternFields), + ...getDataViewColumns(dataView, dataViewFields), ...(combinedRuntimeMappings ? getRuntimeFieldColumns(combinedRuntimeMappings) : []), ]); } - }, [indexPattern, indexPatternFields, combinedRuntimeMappings]); + }, [dataView, dataViewFields, combinedRuntimeMappings]); const dataGrid = useDataGrid(columns); @@ -175,19 +175,19 @@ export const useIndexData = ( setErrorMessage(''); setStatus(INDEX_STATUS.LOADING); - const timeFieldName = indexPattern.getTimeField()?.name; + const timeFieldName = dataView.getTimeField()?.name; const sort: EsSorting = sortingColumns.reduce((s, column) => { s[column.id] = { order: column.direction }; return s; }, {} as EsSorting); const esSearchRequest = { - index: indexPattern.title, + index: dataView.title, body: { query, from: pagination.pageIndex * pagination.pageSize, size: pagination.pageSize, fields: [ - ...(indexPatternFields ?? []), + ...(dataViewFields ?? []), ...(isRuntimeMappings(combinedRuntimeMappings) ? Object.keys(combinedRuntimeMappings) : []), @@ -246,22 +246,22 @@ export const useIndexData = ( } } - if (indexPatternFields !== undefined && query !== undefined) { + if (dataViewFields !== undefined && query !== undefined) { fetchIndexData(); } // custom comparison // eslint-disable-next-line react-hooks/exhaustive-deps }, [ - indexPattern.title, - indexPatternFields, + dataView.title, + dataViewFields, // eslint-disable-next-line react-hooks/exhaustive-deps JSON.stringify([query, pagination, sortingColumns, combinedRuntimeMappings]), ]); const dataLoader = useMemo( - () => new DataLoader(indexPattern, toastNotifications), + () => new DataLoader(dataView, toastNotifications), // eslint-disable-next-line react-hooks/exhaustive-deps - [indexPattern] + [dataView] ); useEffect(() => { @@ -291,16 +291,16 @@ export const useIndexData = ( // eslint-disable-next-line react-hooks/exhaustive-deps }, [ dataGrid.chartsVisible, - indexPattern.title, + dataView.title, // eslint-disable-next-line react-hooks/exhaustive-deps JSON.stringify([query, dataGrid.visibleColumns, runtimeMappings]), ]); - const renderCellValue = useRenderCellValue(indexPattern, pagination, tableItems); + const renderCellValue = useRenderCellValue(dataView, pagination, tableItems); return { ...dataGrid, - indexPatternFields, + dataViewFields, renderCellValue, timeRangeMs, }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index_pattern_prompt.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/data_view_prompt.tsx similarity index 96% rename from x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index_pattern_prompt.tsx rename to x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/data_view_prompt.tsx index cd60be7290b9..922ef80b3d1f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/index_pattern_prompt/index_pattern_prompt.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/data_view_prompt.tsx @@ -15,7 +15,7 @@ interface Props { destIndex?: string; } -export const IndexPatternPrompt: FC = ({ destIndex, color }) => { +export const DataViewPrompt: FC = ({ destIndex, color }) => { const { services: { http: { basePath }, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/index.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/index.ts new file mode 100644 index 000000000000..4c5dbfd0a67b --- /dev/null +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/data_view_prompt/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { DataViewPrompt } from './data_view_prompt'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx index 4e89a2a0833a..d47dc0212f50 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx @@ -59,7 +59,7 @@ import { replaceStringTokens } from '../../../../../util/string_utils'; import { parseInterval } from '../../../../../../../common/util/parse_interval'; import { ExpandableSection, ExpandableSectionProps, HEADER_ITEMS_LOADING } from '.'; -import { IndexPatternPrompt } from '../index_pattern_prompt'; +import { DataViewPrompt } from '../data_view_prompt'; const showingDocs = i18n.translate( 'xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText', @@ -121,9 +121,9 @@ const getResultsSectionHeaderItems = ( interface ExpandableSectionResultsProps { colorRange?: ReturnType; indexData: UseIndexDataReturnType; - indexPattern?: DataView; + dataView?: DataView; jobConfig?: DataFrameAnalyticsConfig; - needsDestIndexPattern: boolean; + needsDestDataView: boolean; resultsField?: string; searchQuery: estypes.QueryDslQueryContainer; } @@ -131,9 +131,9 @@ interface ExpandableSectionResultsProps { export const ExpandableSectionResults: FC = ({ colorRange, indexData, - indexPattern, + dataView, jobConfig, - needsDestIndexPattern, + needsDestDataView, resultsField, searchQuery, }) => { @@ -146,7 +146,7 @@ export const ExpandableSectionResults: FC = ({ }, } = useMlKibana(); - const dataViewId = indexPattern?.id; + const dataViewId = dataView?.id; const discoverLocator = useMemo( () => share.url.locators.get('DISCOVER_APP_LOCATOR'), @@ -206,7 +206,7 @@ export const ExpandableSectionResults: FC = ({ if (discoverLocator !== undefined) { const url = await discoverLocator.getRedirectUrl({ - indexPatternId: dataViewId, + dataViewId, timeRange: data.query.timefilter.timefilter.getTime(), filters: data.query.filterManager.getFilters(), query: { @@ -239,7 +239,7 @@ export const ExpandableSectionResults: FC = ({ if (timeRangeInterval !== null) { // Create a copy of the record as we are adding properties into it. const record = cloneDeep(item); - const timestamp = record[indexPattern!.timeFieldName!]; + const timestamp = record[dataView!.timeFieldName!]; const configuredUrlValue = customUrl.url_value; if (configuredUrlValue.includes('$earliest$')) { @@ -373,9 +373,9 @@ export const ExpandableSectionResults: FC = ({ const resultsSectionContent = ( <> - {jobConfig !== undefined && needsDestIndexPattern && ( + {jobConfig !== undefined && needsDestDataView && (

    - +
    )} {jobConfig !== undefined && @@ -386,7 +386,7 @@ export const ExpandableSectionResults: FC = ({ )} {(columnsWithCharts.length > 0 || searchQuery !== defaultSearchQuery) && - indexPattern !== undefined && ( + dataView !== undefined && ( <> {columnsWithCharts.length > 0 && (tableItems.length > 0 || status === INDEX_STATUS.LOADED) && ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx index 348c7051993a..bd5cd677a714 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_page_wrapper/exploration_page_wrapper.tsx @@ -35,7 +35,7 @@ import { LoadingPanel } from '../loading_panel'; import { FeatureImportanceSummaryPanelProps } from '../total_feature_importance_summary/feature_importance_summary'; import { useExplorationUrlState } from '../../hooks/use_exploration_url_state'; import { ExplorationQueryBarProps } from '../exploration_query_bar/exploration_query_bar'; -import { IndexPatternPrompt } from '../index_pattern_prompt'; +import { DataViewPrompt } from '../data_view_prompt'; function getFilters(resultsField: string) { return { @@ -84,15 +84,15 @@ export const ExplorationPageWrapper: FC = ({ FeatureImportanceSummaryPanel, }) => { const { - indexPattern, - indexPatternErrorMessage, + dataView, + dataViewErrorMessage, isInitialized, isLoadingJobConfig, jobCapsServiceErrorMessage, jobConfig, jobConfigErrorMessage, jobStatus, - needsDestIndexPattern, + needsDestDataView, totalFeatureImportance, } = useResultsViewConfig(jobId); @@ -121,13 +121,13 @@ export const ExplorationPageWrapper: FC = ({ const destIndex = getDestinationIndex(jobConfig); const scatterplotFieldOptions = useScatterplotFieldOptions( - indexPattern, + dataView, jobConfig?.analyzed_fields?.includes, jobConfig?.analyzed_fields?.excludes, resultsField ); - if (indexPatternErrorMessage !== undefined) { + if (dataViewErrorMessage !== undefined) { return ( = ({ iconType="cross" >

    - {indexPatternErrorMessage} - {needsDestIndexPattern ? ( - - ) : null} + {dataViewErrorMessage} + {needsDestDataView ? : null}

    @@ -170,7 +168,7 @@ export const ExplorationPageWrapper: FC = ({ )} - {indexPattern !== undefined && jobConfig && ( + {dataView !== undefined && jobConfig && ( <> @@ -178,7 +176,7 @@ export const ExplorationPageWrapper: FC = ({ = ({ = ({ {isLoadingJobConfig === true && jobConfig === undefined && } {isLoadingJobConfig === false && jobConfig !== undefined && - indexPattern !== undefined && + dataView !== undefined && isInitialized === true && ( )} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index e2998651f2c2..e1efd592e956 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -25,7 +25,7 @@ import { removeFilterFromQueryString } from '../../../../../explorer/explorer_ut import { useMlKibana } from '../../../../../contexts/kibana'; export interface ExplorationQueryBarProps { - indexPattern: DataView; + dataView: DataView; setSearchQuery: (update: { queryString: string; query?: estypes.QueryDslQueryContainer; @@ -41,7 +41,7 @@ export interface ExplorationQueryBarProps { } export const ExplorationQueryBar: FC = ({ - indexPattern, + dataView, setSearchQuery, filters, query, @@ -99,7 +99,7 @@ export const ExplorationQueryBar: FC = ({ case SEARCH_QUERY_LANGUAGE.KUERY: convertedQuery = toElasticsearchQuery( fromKueryExpression(query.query as string), - indexPattern + dataView ); break; case SEARCH_QUERY_LANGUAGE.LUCENE: @@ -181,7 +181,7 @@ export const ExplorationQueryBar: FC = ({ = React.memo( - ({ indexPattern, jobConfig, needsDestIndexPattern, searchQuery }) => { + ({ dataView, jobConfig, needsDestDataView, searchQuery }) => { const { services: { mlServices: { mlApiServices }, @@ -39,7 +39,7 @@ export const ExplorationResultsTable: FC = React.memo( } = useMlKibana(); const classificationData = useExplorationResults( - indexPattern, + dataView, jobConfig, searchQuery, getToastNotifications(), @@ -54,10 +54,10 @@ export const ExplorationResultsTable: FC = React.memo(
    diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index c7216037241d..0a5dd784a649 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -43,7 +43,7 @@ import { useTrainedModelsApiService } from '../../../../../services/ml_api_servi import { useExplorationDataGrid } from './use_exploration_data_grid'; export const useExplorationResults = ( - indexPattern: DataView | undefined, + dataView: DataView | undefined, jobConfig: DataFrameAnalyticsConfig | undefined, searchQuery: estypes.QueryDslQueryContainer, toastNotifications: CoreSetup['notifications']['toasts'], @@ -54,7 +54,7 @@ export const useExplorationResults = ( const trainedModelsApiService = useTrainedModelsApiService(); const needsDestIndexFields = - indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0]; + dataView !== undefined && dataView.title === jobConfig?.source.index[0]; const columns: EuiDataGridColumn[] = []; @@ -90,10 +90,9 @@ export const useExplorationResults = ( }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( - () => - indexPattern !== undefined ? new DataLoader(indexPattern, toastNotifications) : undefined, + () => (dataView !== undefined ? new DataLoader(dataView, toastNotifications) : undefined), // eslint-disable-next-line react-hooks/exhaustive-deps - [indexPattern] + [dataView] ); const fetchColumnChartsData = async function () { @@ -179,7 +178,7 @@ export const useExplorationResults = ( const resultsField = jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD; const renderCellValue = useRenderCellValue( - indexPattern, + dataView, dataGrid.pagination, dataGrid.tableItems, resultsField diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx index 9fc517d293e7..9cbca46a03c8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/job_config_error_callout/job_config_error_callout.tsx @@ -37,7 +37,7 @@ export const JobConfigErrorCallout: FC = ({ application: { getUrlForApp }, }, } = useMlKibana(); - const containsIndexPatternLink = + const containsDataViewLink = typeof jobCapsServiceErrorMessage === 'string' && jobCapsServiceErrorMessage.includes('locate that index-pattern') && jobCapsServiceErrorMessage.includes('click here to re-create'); @@ -45,7 +45,7 @@ export const JobConfigErrorCallout: FC = ({ const message = (

    {jobConfigErrorMessage ? jobConfigErrorMessage : jobCapsServiceErrorMessage}

    ); - const newIndexPatternUrl = useMemo( + const newDataViewUrl = useMemo( () => getUrlForApp('management', { path: 'kibana/indexPatterns', @@ -54,8 +54,8 @@ export const JobConfigErrorCallout: FC = ({ [] ); - const calloutBody = containsIndexPatternLink ? ( - + const calloutBody = containsDataViewLink ? ( + {message} ) : ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx index f8fa311cb8a2..8259ec4188c3 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/outlier_exploration.tsx @@ -33,7 +33,7 @@ import { getFeatureCount } from './common'; import { useOutlierData } from './use_outlier_data'; import { useExplorationUrlState } from '../../hooks/use_exploration_url_state'; import { ExplorationQueryBarProps } from '../exploration_query_bar/exploration_query_bar'; -import { IndexPatternPrompt } from '../index_pattern_prompt'; +import { DataViewPrompt } from '../data_view_prompt'; export type TableItem = Record; @@ -42,12 +42,12 @@ interface ExplorationProps { } export const OutlierExploration: FC = React.memo(({ jobId }) => { - const { indexPattern, indexPatternErrorMessage, jobConfig, needsDestIndexPattern } = + const { dataView, dataViewErrorMessage, jobConfig, needsDestDataView } = useResultsViewConfig(jobId); const [pageUrlState, setPageUrlState] = useExplorationUrlState(); const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); - const outlierData = useOutlierData(indexPattern, jobConfig, searchQuery); + const outlierData = useOutlierData(dataView, jobConfig, searchQuery); const searchQueryUpdateHandler: ExplorationQueryBarProps['setSearchQuery'] = useCallback( (update) => { @@ -81,20 +81,20 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = // If feature influence was enabled for the legacy job we'll show a callout // with some additional information for a workaround. const showLegacyFeatureInfluenceFormatCallout = - !needsDestIndexPattern && + !needsDestDataView && isOutlierAnalysis(jobConfig?.analysis) && jobConfig?.analysis.outlier_detection.compute_feature_influence === true && columnsWithCharts.findIndex((d) => d.id === `${resultsField}.${FEATURE_INFLUENCE}`) === -1; const scatterplotFieldOptions = useScatterplotFieldOptions( - indexPattern, + dataView, jobConfig?.analyzed_fields?.includes, jobConfig?.analyzed_fields?.excludes, resultsField ); const destIndex = getDestinationIndex(jobConfig); - if (indexPatternErrorMessage !== undefined) { + if (dataViewErrorMessage !== undefined) { return ( = React.memo(({ jobId }) = iconType="cross" >

    - {indexPatternErrorMessage} - {needsDestIndexPattern ? ( - - ) : null} + {dataViewErrorMessage} + {needsDestDataView ? : null}

    @@ -124,10 +122,10 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = )} {(columnsWithCharts.length > 0 || searchQuery !== defaultSearchQuery) && - indexPattern !== undefined && ( + dataView !== undefined && ( <> @@ -165,9 +163,9 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = showColorRange && !showLegacyFeatureInfluenceFormatCallout ? colorRange : undefined } indexData={outlierData} - indexPattern={indexPattern} + dataView={dataView} jobConfig={jobConfig} - needsDestIndexPattern={needsDestIndexPattern} + needsDestDataView={needsDestDataView} searchQuery={searchQuery} /> diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index 73d88ecff6a2..4be312056992 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -41,17 +41,17 @@ import { getFeatureCount, getOutlierScoreFieldName } from './common'; import { useExplorationDataGrid } from '../exploration_results_table/use_exploration_data_grid'; export const useOutlierData = ( - indexPattern: DataView | undefined, + dataView: DataView | undefined, jobConfig: DataFrameAnalyticsConfig | undefined, searchQuery: estypes.QueryDslQueryContainer ): UseIndexDataReturnType => { const needsDestIndexFields = - indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0]; + dataView !== undefined && dataView.title === jobConfig?.source.index[0]; const columns = useMemo(() => { const newColumns: EuiDataGridColumn[] = []; - if (jobConfig !== undefined && indexPattern !== undefined) { + if (jobConfig !== undefined && dataView !== undefined) { const resultsField = jobConfig.dest.results_field; const { fieldTypes } = getIndexFields(jobConfig, needsDestIndexFields); newColumns.push( @@ -63,7 +63,7 @@ export const useOutlierData = ( return newColumns; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [jobConfig, indexPattern]); + }, [jobConfig, dataView]); const dataGrid = useExplorationDataGrid( columns, @@ -95,11 +95,8 @@ export const useOutlierData = ( }, [jobConfig && jobConfig.id, dataGrid.pagination, searchQuery, dataGrid.sortingColumns]); const dataLoader = useMemo( - () => - indexPattern !== undefined - ? new DataLoader(indexPattern, getToastNotifications()) - : undefined, - [indexPattern] + () => (dataView !== undefined ? new DataLoader(dataView, getToastNotifications()) : undefined), + [dataView] ); const fetchColumnChartsData = async function () { @@ -146,7 +143,7 @@ export const useOutlierData = ( ); const renderCellValue = useRenderCellValue( - indexPattern, + dataView, dataGrid.pagination, dataGrid.tableItems, jobConfig?.dest.results_field ?? DEFAULT_RESULTS_FIELD, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx index 3d22ed72487f..d18c43cda549 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx @@ -21,12 +21,12 @@ export const DeleteActionModal: FC = ({ closeModal, deleteAndCloseModal, deleteTargetIndex, - deleteIndexPattern, - indexPatternExists, + deleteDataView, + dataViewExists, isLoading, item, toggleDeleteIndex, - toggleDeleteIndexPattern, + toggleDeleteDataView, userCanDeleteIndex, userCanDeleteDataView, }) => { @@ -77,15 +77,15 @@ export const DeleteActionModal: FC = ({ )}
    - {userCanDeleteIndex && indexPatternExists && ( + {userCanDeleteIndex && dataViewExists && ( )} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx index d9a888b9e314..03364165095d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_name.test.tsx @@ -99,7 +99,7 @@ describe('DeleteAction', () => { fireEvent.click(deleteButton); expect(getByTestId('mlAnalyticsJobDeleteModal')).toBeInTheDocument(); expect(queryByTestId('mlAnalyticsJobDeleteIndexSwitch')).toBeNull(); - expect(queryByTestId('mlAnalyticsJobDeleteIndexPatternSwitch')).toBeNull(); + expect(queryByTestId('mlAnalyticsJobDeleteDataViewSwitch')).toBeNull(); mock.mockRestore(); }); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx index 1a828f6b6cdf..f4c2773cd42f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx @@ -42,10 +42,10 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const [isDeleteJobCheckModalVisible, setDeleteJobCheckModalVisible] = useState(false); const [deleteItem, setDeleteItem] = useState(false); const [deleteTargetIndex, setDeleteTargetIndex] = useState(true); - const [deleteIndexPattern, setDeleteIndexPattern] = useState(true); + const [deleteDataView, setDeleteDataView] = useState(true); const [userCanDeleteIndex, setUserCanDeleteIndex] = useState(false); const [userCanDeleteDataView, setUserCanDeleteDataView] = useState(false); - const [indexPatternExists, setIndexPatternExists] = useState(false); + const [dataViewExists, setDataViewExists] = useState(false); const [isLoading, setIsLoading] = useState(false); const { @@ -57,13 +57,13 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const toastNotificationService = useToastNotificationService(); - const checkIndexPatternExists = async () => { + const checkDataViewExists = async () => { try { const dv = (await dataViews.getIdsWithTitle()).find(({ title }) => title === indexName); if (dv !== undefined) { - setIndexPatternExists(true); + setDataViewExists(true); } else { - setIndexPatternExists(false); + setDataViewExists(false); } setIsLoading(false); } catch (e) { @@ -93,7 +93,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { capabilities.indexPatterns.save === true; setUserCanDeleteDataView(canDeleteDataView); if (canDeleteDataView === false) { - setDeleteIndexPattern(false); + setDeleteDataView(false); } } catch (e) { const error = extractErrorMessage(e); @@ -116,7 +116,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { setIsLoading(true); // Check if a data view exists corresponding to current DFA job // if data view does exist, show it to user - checkIndexPatternExists(); + checkDataViewExists(); // Check if an user has permission to delete the index & data view checkUserIndexPermission(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -129,12 +129,12 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { setModalVisible(false); if (item !== undefined) { - if ((userCanDeleteIndex && deleteTargetIndex) || (userCanDeleteIndex && deleteIndexPattern)) { + if ((userCanDeleteIndex && deleteTargetIndex) || (userCanDeleteIndex && deleteDataView)) { deleteAnalyticsAndDestIndex( item.config, item.stats, deleteTargetIndex, - indexPatternExists && deleteIndexPattern, + dataViewExists && deleteDataView, toastNotificationService ); } else { @@ -143,7 +143,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { } }; const toggleDeleteIndex = () => setDeleteTargetIndex(!deleteTargetIndex); - const toggleDeleteIndexPattern = () => setDeleteIndexPattern(!deleteIndexPattern); + const toggleDeleteDataView = () => setDeleteDataView(!deleteDataView); const openModal = (newItem: DataFrameAnalyticsListRowEssentials) => { setItem(newItem); @@ -181,9 +181,9 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { closeModal, deleteAndCloseModal, deleteTargetIndex, - deleteIndexPattern, + deleteDataView, deleteItem, - indexPatternExists, + dataViewExists, isDeleteJobCheckModalVisible, isModalVisible, isLoading, @@ -192,7 +192,7 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { openModal, openDeleteJobCheckModal, toggleDeleteIndex, - toggleDeleteIndexPattern, + toggleDeleteDataView, userCanDeleteIndex, userCanDeleteDataView, }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx index 89c16fbb9305..9525042f6a47 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/source_selection/source_selection.tsx @@ -146,7 +146,7 @@ export const SourceSelection: FC = () => { type: 'index-pattern', getIconForSavedObject: () => 'indexPatternApp', name: i18n.translate( - 'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern', + 'xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView', { defaultMessage: 'Data view', } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts index b9b8de0ce0d5..a1dffe771d8d 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/actions.ts @@ -18,7 +18,7 @@ export enum ACTION { RESET_FORM, SET_ADVANCED_EDITOR_RAW_STRING, SET_FORM_STATE, - SET_INDEX_PATTERN_TITLES, + SET_DATA_VIEW_TITLES, SET_IS_JOB_CREATED, SET_IS_JOB_STARTED, SET_IS_MODAL_BUTTON_DISABLED, @@ -51,9 +51,9 @@ export type Action = } | { type: ACTION.SET_FORM_STATE; payload: Partial } | { - type: ACTION.SET_INDEX_PATTERN_TITLES; + type: ACTION.SET_DATA_VIEW_TITLES; payload: { - indexPatternsMap: SourceIndexMap; + dataViewsMap: SourceIndexMap; }; } | { type: ACTION.SET_IS_JOB_CREATED; isJobCreated: State['isJobCreated'] } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.test.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.test.ts index 1a5beada2c3c..5f02d7bbbb4f 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.test.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.test.ts @@ -39,7 +39,7 @@ const getMockState = ({ jobIdEmpty: false, jobIdValid: true, jobIdExists: false, - createIndexPattern: false, + createDataView: false, }, jobConfig: { source: { index }, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts index 69eececeba12..d2689a009fb1 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/reducer.ts @@ -148,7 +148,7 @@ export const validateNumTopFeatureImportanceValues = ( }; export const validateAdvancedEditor = (state: State): State => { - const { jobIdEmpty, jobIdValid, jobIdExists, jobType, createIndexPattern } = state.form; + const { jobIdEmpty, jobIdValid, jobIdExists, jobType, createDataView } = state.form; const { jobConfig } = state; state.advancedEditorMessages = []; @@ -161,8 +161,7 @@ export const validateAdvancedEditor = (state: State): State => { const destinationIndexName = jobConfig?.dest?.index ?? ''; const destinationIndexNameEmpty = destinationIndexName === ''; const destinationIndexNameValid = isValidIndexName(destinationIndexName); - const destinationIndexPatternTitleExists = - state.indexPatternsMap[destinationIndexName] !== undefined; + const destinationDataViewTitleExists = state.dataViewsMap[destinationIndexName] !== undefined; const analyzedFields = jobConfig?.analyzed_fields?.includes || []; @@ -294,7 +293,7 @@ export const validateAdvancedEditor = (state: State): State => { ), message: '', }); - } else if (destinationIndexPatternTitleExists && !createIndexPattern) { + } else if (destinationDataViewTitleExists && !createDataView) { state.advancedEditorMessages.push({ error: i18n.translate( 'xpack.ml.dataframe.analytics.create.advancedEditorMessage.destinationIndexNameExistsWarn', @@ -360,7 +359,7 @@ export const validateAdvancedEditor = (state: State): State => { }); } - state.form.destinationIndexPatternTitleExists = destinationIndexPatternTitleExists; + state.form.destinationDataViewTitleExists = destinationDataViewTitleExists; state.isValid = includesValid && @@ -377,7 +376,7 @@ export const validateAdvancedEditor = (state: State): State => { !dependentVariableEmpty && !modelMemoryLimitEmpty && (numTopFeatureImportanceValuesValid || jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) && - (!destinationIndexPatternTitleExists || !createIndexPattern); + (!destinationDataViewTitleExists || !createDataView); return state; }; @@ -425,8 +424,8 @@ const validateForm = (state: State): State => { sourceIndexNameValid, destinationIndexNameEmpty, destinationIndexNameValid, - destinationIndexPatternTitleExists, - createIndexPattern, + destinationDataViewTitleExists, + createDataView, dependentVariable, modelMemoryLimit, numTopFeatureImportanceValuesValid, @@ -458,7 +457,7 @@ const validateForm = (state: State): State => { destinationIndexNameValid && !dependentVariableEmpty && (numTopFeatureImportanceValuesValid || jobType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION) && - (!destinationIndexPatternTitleExists || !createIndexPattern); + (!destinationDataViewTitleExists || !createDataView); return state; }; @@ -513,8 +512,8 @@ export function reducer(state: State, action: Action): State { if (action.payload.destinationIndex !== undefined) { newFormState.destinationIndexNameEmpty = newFormState.destinationIndex === ''; newFormState.destinationIndexNameValid = isValidIndexName(newFormState.destinationIndex); - newFormState.destinationIndexPatternTitleExists = - state.indexPatternsMap[newFormState.destinationIndex] !== undefined; + newFormState.destinationDataViewTitleExists = + state.dataViewsMap[newFormState.destinationIndex] !== undefined; } if (action.payload.jobId !== undefined) { @@ -541,13 +540,13 @@ export function reducer(state: State, action: Action): State { ? validateAdvancedEditor({ ...state, form: newFormState }) : validateForm({ ...state, form: newFormState }); - case ACTION.SET_INDEX_PATTERN_TITLES: { + case ACTION.SET_DATA_VIEW_TITLES: { const newState = { ...state, ...action.payload, }; - newState.form.destinationIndexPatternTitleExists = - newState.indexPatternsMap[newState.form.destinationIndex] !== undefined; + newState.form.destinationDataViewTitleExists = + newState.dataViewsMap[newState.form.destinationIndex] !== undefined; return newState; } @@ -591,8 +590,8 @@ export function reducer(state: State, action: Action): State { formState.destinationIndexNameEmpty = formState.destinationIndex === ''; formState.destinationIndexNameValid = isValidIndexName(formState.destinationIndex || ''); - formState.destinationIndexPatternTitleExists = - state.indexPatternsMap[formState.destinationIndex || ''] !== undefined; + formState.destinationDataViewTitleExists = + state.dataViewsMap[formState.destinationIndex || ''] !== undefined; if (formState.numTopFeatureImportanceValues !== undefined) { formState.numTopFeatureImportanceValuesValid = validateNumTopFeatureImportanceValues( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts index d567c7d19b3d..efffc221c317 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/state.ts @@ -35,13 +35,10 @@ export const UNSET_CONFIG_ITEM = '--'; export type EsIndexName = string; export type DependentVariable = string; -export type IndexPatternTitle = string; +export type DataViewTitle = string; export type AnalyticsJobType = DataFrameAnalysisConfigType | undefined; -type IndexPatternId = string; -export type SourceIndexMap = Record< - IndexPatternTitle, - { label: IndexPatternTitle; value: IndexPatternId } ->; +type DataViewId = string; +export type SourceIndexMap = Record; export interface FormMessage { error?: string; @@ -55,7 +52,7 @@ export interface State { form: { alpha: undefined | number; computeFeatureInfluence: string; - createIndexPattern: boolean; + createDataView: boolean; classAssignmentObjective: undefined | string; dependentVariable: DependentVariable; description: string; @@ -63,7 +60,7 @@ export interface State { destinationIndexNameExists: boolean; destinationIndexNameEmpty: boolean; destinationIndexNameValid: boolean; - destinationIndexPatternTitleExists: boolean; + destinationDataViewTitleExists: boolean; downsampleFactor: undefined | number; earlyStoppingEnabled: undefined | boolean; eta: undefined | number; @@ -120,7 +117,7 @@ export interface State { useEstimatedMml: boolean; }; disabled: boolean; - indexPatternsMap: SourceIndexMap; + dataViewsMap: SourceIndexMap; isAdvancedEditorEnabled: boolean; isAdvancedEditorValidJson: boolean; hasSwitchedToEditor: boolean; @@ -141,7 +138,7 @@ export const getInitialState = (): State => ({ form: { alpha: undefined, computeFeatureInfluence: 'true', - createIndexPattern: true, + createDataView: true, classAssignmentObjective: undefined, dependentVariable: '', description: '', @@ -149,7 +146,7 @@ export const getInitialState = (): State => ({ destinationIndexNameExists: false, destinationIndexNameEmpty: true, destinationIndexNameValid: false, - destinationIndexPatternTitleExists: false, + destinationDataViewTitleExists: false, earlyStoppingEnabled: undefined, downsampleFactor: undefined, eta: undefined, @@ -210,7 +207,7 @@ export const getInitialState = (): State => ({ !mlNodesAvailable() || !checkPermission('canCreateDataFrameAnalytics') || !checkPermission('canStartStopDataFrameAnalytics'), - indexPatternsMap: {}, + dataViewsMap: {}, isAdvancedEditorEnabled: false, isAdvancedEditorValidJson: true, hasSwitchedToEditor: false, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts index e7b618808100..d0dbfe24fb9b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/hooks/use_create_analytics_form/use_create_analytics_form.ts @@ -59,7 +59,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const { refresh } = useRefreshAnalyticsList(); const { form, jobConfig, isAdvancedEditorEnabled } = state; - const { createIndexPattern, jobId } = form; + const { createDataView, jobId } = form; let { destinationIndex } = form; const addRequestMessage = (requestMessage: FormMessage) => @@ -73,8 +73,8 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const setAdvancedEditorRawString = (advancedEditorRawString: string) => dispatch({ type: ACTION.SET_ADVANCED_EDITOR_RAW_STRING, advancedEditorRawString }); - const setIndexPatternTitles = (payload: { indexPatternsMap: SourceIndexMap }) => - dispatch({ type: ACTION.SET_INDEX_PATTERN_TITLES, payload }); + const setDataViewTitles = (payload: { dataViewsMap: SourceIndexMap }) => + dispatch({ type: ACTION.SET_DATA_VIEW_TITLES, payload }); const setIsJobCreated = (isJobCreated: boolean) => dispatch({ type: ACTION.SET_IS_JOB_CREATED, isJobCreated }); @@ -110,7 +110,7 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { ), }); setIsJobCreated(true); - if (createIndexPattern) { + if (createDataView) { createKibanaDataView(destinationIndex, dataViews, form.timeFieldName, addRequestMessage); } refresh(); @@ -132,17 +132,17 @@ export const useCreateAnalyticsForm = (): CreateAnalyticsFormProps => { const prepareFormValidation = async () => { try { // Set the existing data view names. - const indexPatternsMap: SourceIndexMap = {}; + const dataViewsMap: SourceIndexMap = {}; const savedObjects = (await dataViews.getCache()) || []; savedObjects.forEach((obj) => { const title = obj?.attributes?.title; if (title !== undefined) { const id = obj?.id || ''; - indexPatternsMap[title] = { label: title, value: id }; + dataViewsMap[title] = { label: title, value: id }; } }); - setIndexPatternTitles({ - indexPatternsMap, + setDataViewTitles({ + dataViewsMap, }); } catch (e) { addRequestMessage({ diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts index 8929f39bea43..ea3c24884bbe 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/services/analytics_service/delete_analytics.ts @@ -48,7 +48,7 @@ export const deleteAnalyticsAndDestIndex = async ( analyticsConfig: DataFrameAnalyticsListRow['config'], analyticsStats: DataFrameAnalyticsListRow['stats'], deleteDestIndex: boolean, - deleteDestIndexPattern: boolean, + deleteDestDataView: boolean, toastNotificationService: ToastNotificationService ) => { const destinationIndex = analyticsConfig.dest.index; @@ -59,7 +59,7 @@ export const deleteAnalyticsAndDestIndex = async ( const status = await ml.dataFrameAnalytics.deleteDataFrameAnalyticsAndDestIndex( analyticsConfig.id, deleteDestIndex, - deleteDestIndexPattern + deleteDestDataView ); if (status.analyticsJobDeleted?.success) { toastNotificationService.displaySuccessToast( @@ -97,7 +97,7 @@ export const deleteAnalyticsAndDestIndex = async ( ); } - if (status.destIndexPatternDeleted?.success) { + if (status.destDataViewDeleted?.success) { toastNotificationService.displaySuccessToast( i18n.translate( 'xpack.ml.dataframe.analyticsList.deleteAnalyticsWithDataViewSuccessMessage', @@ -108,8 +108,8 @@ export const deleteAnalyticsAndDestIndex = async ( ) ); } - if (status.destIndexPatternDeleted?.error) { - const error = extractErrorMessage(status.destIndexPatternDeleted.error); + if (status.destDataViewDeleted?.error) { + const error = extractErrorMessage(status.destDataViewDeleted.error); toastNotificationService.displayDangerToast( i18n.translate('xpack.ml.dataframe.analyticsList.deleteAnalyticsWithDataViewErrorMessage', { defaultMessage: 'An error occurred deleting data view {destinationIndex}: {error}', diff --git a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx index 721f0958ba5f..d202ffbd38b3 100644 --- a/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx +++ b/x-pack/plugins/ml/public/application/explorer/swimlane_container.tsx @@ -160,6 +160,7 @@ export interface SwimlaneProps { showYAxis?: boolean; yAxisWidth?: HeatmapStyle['yAxisLabel']['width']; chartsService: ChartsPluginStart; + onRenderComplete?: () => void; } /** @@ -187,6 +188,7 @@ export const SwimlaneContainer: FC = ({ showLegend = true, 'data-test-subj': dataTestSubj, yAxisWidth, + onRenderComplete, }) => { const [chartWidth, setChartWidth] = useState(0); @@ -453,6 +455,11 @@ export const SwimlaneContainer: FC = ({ debugState={window._echDebugStateFlag ?? false} onBrushEnd={onBrushEnd as BrushEndListener} locale={i18n.getLocale()} + onRenderChange={(isRendered) => { + if (isRendered && onRenderComplete) { + onRenderComplete(); + } + }} /> j.blocked !== undefined)) { + if ( + blockingJobsRefreshTimeout === null && + jobsSummaryList.some((j) => j.blocked !== undefined) + ) { // if there are some jobs in a deleting state, start polling for // deleting jobs so we can update the jobs list once the // deleting tasks are over diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts index 4b4ce7299277..f5f491426b0a 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_dashboard/quick_create_job_base.ts @@ -69,21 +69,21 @@ export class QuickJobCreatorBase { datafeedConfig, jobConfig, createdByLabel, - dashboard, start, end, startJob, runInRealTime, + dashboard, }: { jobId: string; datafeedConfig: Datafeed; jobConfig: Job; createdByLabel: CREATED_BY_LABEL; - dashboard: Dashboard; start: number | undefined; end: number | undefined; startJob: boolean; runInRealTime: boolean; + dashboard?: Dashboard; }) { const datafeedId = createDatafeedId(jobId); const datafeed = { ...datafeedConfig, job_id: jobId, datafeed_id: datafeedId }; @@ -93,7 +93,7 @@ export class QuickJobCreatorBase { job_id: jobId, custom_settings: { created_by: createdByLabel, - ...(await this.getCustomUrls(dashboard, datafeed)), + ...(dashboard ? await this.getCustomUrls(dashboard, datafeed) : {}), }, }; @@ -230,7 +230,7 @@ export class QuickJobCreatorBase { return mergedQueries; } - protected async createDashboardLink(dashboard: Dashboard, datafeedConfig: estypes.MlDatafeed) { + private async createDashboardLink(dashboard: Dashboard, datafeedConfig: estypes.MlDatafeed) { const dashboardTitle = dashboard?.getTitle(); if (dashboardTitle === undefined || dashboardTitle === '') { // embeddable may have not been in a dashboard @@ -274,7 +274,7 @@ export class QuickJobCreatorBase { return { url_name: urlName, url_value: url, time_range: 'auto' }; } - protected async getCustomUrls(dashboard: Dashboard, datafeedConfig: estypes.MlDatafeed) { + private async getCustomUrls(dashboard: Dashboard, datafeedConfig: estypes.MlDatafeed) { const customUrls = await this.createDashboardLink(dashboard, datafeedConfig); return dashboard !== undefined && customUrls !== null ? { custom_urls: [customUrls] } : {}; } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts index 2ade08c3cf23..4df2b74347f4 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/quick_create_job.ts @@ -135,7 +135,7 @@ export class QuickLensJobCreator extends QuickJobCreatorBase { } } - async createJob( + private async createJob( chartInfo: ChartInfo, startString: string, endString: string, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts index 9dcce1facf29..c8ad1ee6942e 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_lens/route_resolver.ts @@ -15,7 +15,7 @@ import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import { QuickLensJobCreator } from './quick_create_job'; import type { MlApiServices } from '../../../services/ml_api_service'; -import { getDefaultQuery } from '../utils/new_job_utils'; +import { getDefaultQuery, getRisonValue } from '../utils/new_job_utils'; interface Dependencies { lens: LensPublicStart; @@ -27,8 +27,8 @@ interface Dependencies { export async function resolver( deps: Dependencies, lensSavedObjectRisonString: string | undefined, - fromRisonStrong: string, - toRisonStrong: string, + fromRisonString: string, + toRisonString: string, queryRisonString: string, filtersRisonString: string, layerIndexRisonString: string @@ -43,37 +43,11 @@ export async function resolver( throw new Error('Cannot create visualization'); } - let query: Query; - let filters: Filter[]; - try { - query = rison.decode(queryRisonString) as Query; - } catch (error) { - query = getDefaultQuery(); - } - try { - filters = rison.decode(filtersRisonString) as Filter[]; - } catch (error) { - filters = []; - } - - let from: string; - let to: string; - try { - from = rison.decode(fromRisonStrong) as string; - } catch (error) { - from = ''; - } - try { - to = rison.decode(toRisonStrong) as string; - } catch (error) { - to = ''; - } - let layerIndex: number | undefined; - try { - layerIndex = rison.decode(layerIndexRisonString) as number; - } catch (error) { - layerIndex = undefined; - } + const query = getRisonValue(queryRisonString, getDefaultQuery()) as Query; + const filters = getRisonValue(filtersRisonString, []); + const from = getRisonValue(fromRisonString, ''); + const to = getRisonValue(toRisonString, ''); + const layerIndex = getRisonValue(layerIndexRisonString, undefined); const jobCreator = new QuickLensJobCreator( lens, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts index e590600cd404..954abd2d14ab 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/quick_create_job.ts @@ -162,7 +162,7 @@ export class QuickGeoJobCreator extends QuickJobCreatorBase { } } - async createGeoJob({ + private async createGeoJob({ dataViewId, sourceDataView, from, diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts index 39753c77038c..0728ca3c61d5 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_map/route_resolver.ts @@ -5,16 +5,13 @@ * 2.0. */ -import rison from '@kbn/rison'; -import type { Query } from '@kbn/es-query'; -import type { Filter } from '@kbn/es-query'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; import type { TimefilterContract } from '@kbn/data-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import type { MlApiServices } from '../../../services/ml_api_service'; import { QuickGeoJobCreator } from './quick_create_job'; -import { getDefaultQuery } from '../utils/new_job_utils'; +import { getDefaultQuery, getRisonValue } from '../utils/new_job_utils'; interface Dependencies { kibanaConfig: IUiSettingsClient; @@ -24,66 +21,32 @@ interface Dependencies { } export async function resolver( deps: Dependencies, - dashboard: string, - dataViewId: string, - embeddable: string, - geoField: string, - splitField: string, + dashboardRisonString: string, + dataViewIdRisonString: string, + embeddableRisonString: string, + geoFieldRisonString: string, + splitFieldRisonString: string, fromRisonString: string, toRisonString: string, - layer?: string + layerRisonString?: string ) { const { kibanaConfig, timeFilter, dashboardService, mlApiServices } = deps; - let decodedDashboard; - let decodedEmbeddable; - let decodedLayer; - let splitFieldDecoded; - let dvId; + const defaultLayer = { query: getDefaultQuery(), filters: [] }; - try { - dvId = rison.decode(dataViewId) as string; - } catch (error) { - dvId = ''; - } + const dashboard = getRisonValue(dashboardRisonString, defaultLayer); + const embeddable = getRisonValue(embeddableRisonString, defaultLayer); - try { - decodedDashboard = rison.decode(dashboard) as { query: Query; filters: Filter[] }; - } catch (error) { - decodedDashboard = { query: getDefaultQuery(), filters: [] }; - } + const layer = + layerRisonString !== undefined + ? getRisonValue(layerRisonString, defaultLayer) + : defaultLayer; - try { - decodedEmbeddable = rison.decode(embeddable) as { query: Query; filters: Filter[] }; - } catch (error) { - decodedEmbeddable = { query: getDefaultQuery(), filters: [] }; - } + const geoField = getRisonValue(geoFieldRisonString, ''); + const splitField = getRisonValue(splitFieldRisonString, null); + const dataViewId = getRisonValue(dataViewIdRisonString, ''); - if (layer) { - try { - decodedLayer = rison.decode(layer) as { query: Query }; - } catch (error) { - decodedLayer = { query: getDefaultQuery(), filters: [] }; - } - } - - try { - splitFieldDecoded = rison.decode(splitField) as string; - } catch (error) { - splitFieldDecoded = null; - } - - let from: string; - let to: string; - try { - from = rison.decode(fromRisonString) as string; - } catch (error) { - from = ''; - } - try { - to = rison.decode(toRisonString) as string; - } catch (error) { - to = ''; - } + const from = getRisonValue(fromRisonString, ''); + const to = getRisonValue(toRisonString, ''); const jobCreator = new QuickGeoJobCreator( kibanaConfig, @@ -93,15 +56,15 @@ export async function resolver( ); await jobCreator.createAndStashGeoJob( - dvId, + dataViewId, from, to, - decodedDashboard.query, - decodedDashboard.filters, - decodedEmbeddable.query, - decodedEmbeddable.filters, + dashboard.query, + dashboard.filters, + embeddable.query, + embeddable.filters, geoField, - splitFieldDecoded, - decodedLayer?.query + splitField, + layer?.query ); } diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/index.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/index.ts new file mode 100644 index 000000000000..51b3194f28c9 --- /dev/null +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/index.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { + QuickCategorizationJobCreator, + CATEGORIZATION_TYPE, + type CategorizationType, +} from './quick_create_job'; + +export { resolver } from './route_resolver'; diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts new file mode 100644 index 000000000000..721d48d1908b --- /dev/null +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/quick_create_job.ts @@ -0,0 +1,209 @@ +/* + * 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 { IUiSettingsClient } from '@kbn/core/public'; +import type { DataPublicPluginStart, TimefilterContract } from '@kbn/data-plugin/public'; +import type { DashboardStart } from '@kbn/dashboard-plugin/public'; +import { DataViewField, DataView } from '@kbn/data-views-plugin/common'; +import type { TimeRange } from '@kbn/es-query'; +import { i18n } from '@kbn/i18n'; +import { MLCATEGORY, ML_JOB_AGGREGATION } from '@kbn/ml-anomaly-utils'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { CREATED_BY_LABEL, DEFAULT_BUCKET_SPAN } from '../../../../../common/constants/new_job'; +import { type CreateState, QuickJobCreatorBase } from '../job_from_dashboard/quick_create_job_base'; +import type { MlApiServices } from '../../../services/ml_api_service'; +import { createEmptyDatafeed, createEmptyJob } from '../common/job_creator/util/default_configs'; +import { stashJobForCloning } from '../common/job_creator/util/general'; +import type { JobCreatorType } from '../common/job_creator'; + +export const CATEGORIZATION_TYPE = { + COUNT: ML_JOB_AGGREGATION.COUNT, + RARE: ML_JOB_AGGREGATION.RARE, +} as const; + +export type CategorizationType = typeof CATEGORIZATION_TYPE[keyof typeof CATEGORIZATION_TYPE]; + +export class QuickCategorizationJobCreator extends QuickJobCreatorBase { + constructor( + kibanaConfig: IUiSettingsClient, + timeFilter: TimefilterContract, + dashboardService: DashboardStart, + private data: DataPublicPluginStart, + mlApiServices: MlApiServices + ) { + super(kibanaConfig, timeFilter, dashboardService, mlApiServices); + } + + public async createAndSaveJob( + categorizationType: CategorizationType, + jobId: string, + bucketSpan: string, + dataView: DataView, + field: DataViewField, + partitionField: DataViewField | null, + stopOnWarn: boolean, + query: QueryDslQueryContainer, + timeRange: TimeRange, + startJob: boolean, + runInRealTime: boolean + ): Promise { + if (query === undefined) { + throw new Error('Cannot create job, query and filters are undefined'); + } + + const { jobConfig, datafeedConfig, start, end } = await this.createJob( + categorizationType, + dataView, + field, + partitionField, + stopOnWarn, + timeRange, + query, + bucketSpan + ); + const createdByLabel = CREATED_BY_LABEL.CATEGORIZATION_FROM_PATTERN_ANALYSIS; + + const result = await this.putJobAndDataFeed({ + jobId, + datafeedConfig, + jobConfig, + createdByLabel, + start, + end, + startJob, + runInRealTime, + }); + return result; + } + + public async createAndStashADJob( + categorizationType: CategorizationType, + dataViewId: string, + fieldName: string, + partitionFieldName: string | null, + stopOnWarn: boolean, + startString: string, + endString: string, + query: QueryDslQueryContainer + ) { + try { + const dataView = await this.data.dataViews.get(dataViewId); + const field = dataView.getFieldByName(fieldName); + const partitionField = partitionFieldName + ? dataView.getFieldByName(partitionFieldName) ?? null + : null; + + if (field === undefined) { + throw new Error('Cannot create job, field is undefined'); + } + + const { jobConfig, datafeedConfig, start, end, includeTimeRange } = await this.createJob( + categorizationType, + dataView, + field, + partitionField, + stopOnWarn, + { from: startString, to: endString }, + query, + DEFAULT_BUCKET_SPAN + ); + + // add job config and start and end dates to the + // job cloning stash, so they can be used + // by the new job wizards + stashJobForCloning( + { + jobConfig, + datafeedConfig, + createdBy: CREATED_BY_LABEL.CATEGORIZATION_FROM_PATTERN_ANALYSIS, + start, + end, + } as JobCreatorType, + true, + includeTimeRange, + !includeTimeRange + ); + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + } + } + + private async createJob( + categorizationType: CategorizationType, + dataView: DataView, + field: DataViewField, + partitionField: DataViewField | null, + stopOnWarn: boolean, + timeRange: TimeRange, + query: QueryDslQueryContainer, + bucketSpan: string + ) { + const jobConfig = createEmptyJob(); + const datafeedConfig = createEmptyDatafeed(dataView.getIndexPattern()); + + datafeedConfig.query = query; + jobConfig.analysis_config = { + categorization_field_name: field.name, + per_partition_categorization: { + enabled: partitionField !== null, + stop_on_warn: stopOnWarn, + }, + influencers: [MLCATEGORY], + detectors: [ + { + function: categorizationType, + by_field_name: MLCATEGORY, + }, + ], + bucket_span: bucketSpan, + }; + + if (partitionField !== null) { + jobConfig.analysis_config.detectors[0].partition_field_name = partitionField.name; + jobConfig.analysis_config.influencers!.push(partitionField.name); + } + + jobConfig.data_description.time_field = dataView.timeFieldName; + + let start: number | undefined; + let end: number | undefined; + let includeTimeRange = true; + + try { + // attempt to parse the start and end dates. + // if start and end values cannot be determined + // instruct the job cloning code to auto-select the + // full time range for the index. + const { min, max } = this.timeFilter.calculateBounds(timeRange); + start = min?.valueOf(); + end = max?.valueOf(); + + if (start === undefined || end === undefined || isNaN(start) || isNaN(end)) { + throw Error( + i18n.translate('xpack.ml.newJob.fromLens.createJob.error.timeRange', { + defaultMessage: 'Incompatible time range', + }) + ); + } + } catch (error) { + // eslint-disable-next-line no-console + console.error(error); + includeTimeRange = false; + start = undefined; + end = undefined; + } + + return { + jobConfig, + datafeedConfig, + start, + end, + includeTimeRange, + }; + } +} diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts new file mode 100644 index 000000000000..0f8462128d2c --- /dev/null +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/route_resolver.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import type { DataPublicPluginStart, TimefilterContract } from '@kbn/data-plugin/public'; +import type { DashboardStart } from '@kbn/dashboard-plugin/public'; +import type { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types'; +import { + type CategorizationType, + QuickCategorizationJobCreator, + CATEGORIZATION_TYPE, +} from './quick_create_job'; +import type { MlApiServices } from '../../../services/ml_api_service'; + +import { getDefaultDatafeedQuery, getRisonValue } from '../utils/new_job_utils'; + +interface Dependencies { + kibanaConfig: IUiSettingsClient; + timeFilter: TimefilterContract; + dashboardService: DashboardStart; + data: DataPublicPluginStart; + mlApiServices: MlApiServices; +} +export async function resolver( + deps: Dependencies, + categorizationTypeRisonString: string, + dataViewIdRisonString: string, + fieldRisonString: string, + partitionFieldRisonString: string | null, + stopOnWarnRisonString: string, + fromRisonString: string, + toRisonString: string, + queryRisonString: string +) { + const { mlApiServices, timeFilter, kibanaConfig, dashboardService, data } = deps; + + const query = getRisonValue(queryRisonString, getDefaultDatafeedQuery()); + const from = getRisonValue(fromRisonString, ''); + const to = getRisonValue(toRisonString, ''); + const categorizationType = getRisonValue( + categorizationTypeRisonString, + CATEGORIZATION_TYPE.COUNT + ); + const dataViewId = getRisonValue(dataViewIdRisonString, ''); + const field = getRisonValue(fieldRisonString, ''); + const partitionField = + partitionFieldRisonString === null ? '' : getRisonValue(partitionFieldRisonString, ''); + const stopOnWarn = getRisonValue(stopOnWarnRisonString, false); + + const jobCreator = new QuickCategorizationJobCreator( + kibanaConfig, + timeFilter, + dashboardService, + data, + mlApiServices + ); + await jobCreator.createAndStashADJob( + categorizationType, + dataViewId, + field, + partitionField, + stopOnWarn, + from, + to, + query + ); +} diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/utils.ts b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/utils.ts new file mode 100644 index 000000000000..4bc84a4df20d --- /dev/null +++ b/x-pack/plugins/ml/public/application/jobs/new_job/job_from_pattern_analysis/utils.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataViewField, DataView } from '@kbn/data-views-plugin/common'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; +import type { TimeRange } from '@kbn/es-query'; +import { ML_APP_LOCATOR } from '../../../../../common/constants/locator'; +import { ML_PAGES } from '../../../../locator'; +import type { CategorizationType } from './quick_create_job'; + +export async function redirectToADJobWizards( + categorizationType: CategorizationType, + dataView: DataView, + field: DataViewField, + partitionField: DataViewField | null, + stopOnWarn: boolean, + query: QueryDslQueryContainer, + timeRange: TimeRange, + share: SharePluginStart +) { + const locator = share.url.locators.get(ML_APP_LOCATOR)!; + + const url = await locator.getUrl({ + page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS, + pageState: { + categorizationType, + dataViewId: dataView.id, + field: field.name, + partitionField: partitionField?.name || null, + stopOnWarn, + from: timeRange.from, + to: timeRange.to, + query: JSON.stringify(query), + }, + }); + + window.open(url, '_blank'); +} diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts index b13cde5e94cc..ba31ff5e4cd9 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/pages/index_or_search/preconfigured_job_redirect.ts @@ -55,6 +55,7 @@ async function getWizardUrlFromCloningJob(createdBy: string | undefined, dataVie page = JOB_TYPE.POPULATION; break; case CREATED_BY_LABEL.CATEGORIZATION: + case CREATED_BY_LABEL.CATEGORIZATION_FROM_PATTERN_ANALYSIS: page = JOB_TYPE.CATEGORIZATION; break; case CREATED_BY_LABEL.RARE: diff --git a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts index 32fd17c9d1f1..eef866da2d28 100644 --- a/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts +++ b/x-pack/plugins/ml/public/application/jobs/new_job/utils/new_job_utils.ts @@ -7,6 +7,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { cloneDeep } from 'lodash'; +import rison from '@kbn/rison'; import { Query, fromKueryExpression, @@ -162,3 +163,14 @@ export function checkCardinalitySuccess(data: any) { return response; } + +export function getRisonValue( + risonString: string, + defaultValue: T +) { + try { + return rison.decode(risonString) as T; + } catch (error) { + return defaultValue; + } +} diff --git a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx index 7c39528cf5b4..0b6600e981f0 100644 --- a/x-pack/plugins/ml/public/application/model_management/model_actions.tsx +++ b/x-pack/plugins/ml/public/application/model_management/model_actions.tsx @@ -130,18 +130,19 @@ export function useModelActions({ return useMemo( () => [ { - name: i18n.translate('xpack.ml.trainedModels.modelsList.viewTrainingDataActionLabel', { + name: i18n.translate('xpack.ml.trainedModels.modelsList.viewTrainingDataNameActionLabel', { defaultMessage: 'View training data', }), description: i18n.translate( 'xpack.ml.trainedModels.modelsList.viewTrainingDataActionLabel', { - defaultMessage: 'View training data', + defaultMessage: 'Training data can be viewed when data frame analytics job exists.', } ), icon: 'visTable', type: 'icon', available: (item) => !!item.metadata?.analytics_config?.id, + enabled: (item) => item.origin_job_exists === true, onClick: async (item) => { if (item.metadata?.analytics_config === undefined) return; @@ -164,7 +165,6 @@ export function useModelActions({ await navigateToUrl(url); }, - isPrimary: true, }, { name: i18n.translate('xpack.ml.inference.modelsList.analyticsMapActionLabel', { @@ -481,7 +481,7 @@ export function useModelActions({ ); }, enabled: (item) => { - return item.state !== MODEL_STATE.STARTED; + return canStartStopTrainedModels && item.state !== MODEL_STATE.STARTED; }, }, { diff --git a/x-pack/plugins/ml/public/application/model_management/models_list.tsx b/x-pack/plugins/ml/public/application/model_management/models_list.tsx index 56486d1bbbd4..e9672729b6f4 100644 --- a/x-pack/plugins/ml/public/application/model_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/model_management/models_list.tsx @@ -79,6 +79,7 @@ export type ModelItem = TrainedModelConfigResponse & { type?: string[]; stats?: Stats & { deployment_stats: TrainedModelDeploymentStatsResponse[] }; pipelines?: ModelPipelines['pipelines'] | null; + origin_job_exists?: boolean; deployment_ids: string[]; putModelConfig?: object; state: ModelState; diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx new file mode 100644 index 000000000000..1ac93184f201 --- /dev/null +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/from_pattern_analysis.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { Redirect } from 'react-router-dom'; +import { parse } from 'query-string'; +import { useMlKibana } from '../../../contexts/kibana'; +import { ML_PAGES } from '../../../../locator'; +import { createPath, MlRoute, PageLoader, PageProps } from '../../router'; +import { useRouteResolver } from '../../use_resolver'; +import { resolver } from '../../../jobs/new_job/job_from_pattern_analysis'; + +export const fromPatternAnalysisRouteFactory = (): MlRoute => ({ + path: createPath(ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS), + render: (props, deps) => , + breadcrumbs: [], +}); + +const PageWrapper: FC = ({ location }) => { + const { + categorizationType, + dataViewId, + field, + partitionField, + stopOnWarn, + from, + to, + query, + }: Record = parse(location.search, { + sort: false, + }); + const { + services: { + data, + dashboard: dashboardService, + uiSettings: kibanaConfig, + mlServices: { mlApiServices }, + }, + } = useMlKibana(); + + const { context } = useRouteResolver('full', ['canCreateJob'], { + redirect: () => + resolver( + { + mlApiServices, + timeFilter: data.query.timefilter.timefilter, + kibanaConfig, + dashboardService, + data, + }, + categorizationType, + dataViewId, + field, + partitionField, + stopOnWarn, + from, + to, + query + ), + }); + + return ( + + {} + + ); +}; diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/index.ts b/x-pack/plugins/ml/public/application/routing/routes/new_job/index.ts index 675b391d1e82..d4876aba2444 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/index.ts +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/index.ts @@ -12,3 +12,4 @@ export * from './wizard'; export * from './recognize'; export * from './from_lens'; export * from './from_map'; +export * from './from_pattern_analysis'; diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts index 9d9d0f859655..6381f8d6e514 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/data_frame_analytics.ts @@ -49,7 +49,7 @@ export interface DeleteDataFrameAnalyticsWithIndexResponse { acknowledged: boolean; analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus; destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus; - destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus; + destDataViewDeleted: DeleteDataFrameAnalyticsWithIndexStatus; } export interface JobsExistsResponse { @@ -152,11 +152,11 @@ export const dataFrameAnalyticsApiProvider = (httpService: HttpService) => ({ deleteDataFrameAnalyticsAndDestIndex( analyticsId: string, deleteDestIndex: boolean, - deleteDestIndexPattern: boolean + deleteDestDataView: boolean ) { return httpService.http({ path: `${ML_INTERNAL_BASE_PATH}/data_frame/analytics/${analyticsId}`, - query: { deleteDestIndex, deleteDestIndexPattern }, + query: { deleteDestIndex, deleteDestDataView }, method: 'DELETE', version: '1', }); diff --git a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts index f073c4afea84..511a1a1457b0 100644 --- a/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts +++ b/x-pack/plugins/ml/public/application/services/new_job_capabilities/new_job_capabilities_service.ts @@ -14,15 +14,21 @@ import { EVENT_RATE_FIELD_ID, } from '@kbn/ml-anomaly-utils'; import { getGeoFields, filterCategoryFields } from '../../../../common/util/fields_utils'; -import { ml } from '../ml_api_service'; +import { ml, type MlApiServices } from '../ml_api_service'; import { processTextAndKeywordFields, NewJobCapabilitiesServiceBase } from './new_job_capabilities'; -class NewJobCapsService extends NewJobCapabilitiesServiceBase { +export class NewJobCapsService extends NewJobCapabilitiesServiceBase { private _catFields: Field[] = []; private _dateFields: Field[] = []; private _geoFields: Field[] = []; private _includeEventRateField: boolean = true; private _removeTextFields: boolean = true; + private _mlApiService: MlApiServices; + + constructor(mlApiService: MlApiServices) { + super(); + this._mlApiService = mlApiService; + } public get catFields(): Field[] { return this._catFields; @@ -49,7 +55,10 @@ class NewJobCapsService extends NewJobCapabilitiesServiceBase { this._includeEventRateField = includeEventRateField; this._removeTextFields = removeTextFields; - const resp = await ml.jobs.newJobCaps(dataView.getIndexPattern(), dataView.type === 'rollup'); + const resp = await this._mlApiService.jobs.newJobCaps( + dataView.getIndexPattern(), + dataView.type === 'rollup' + ); const { fields: allFields, aggs } = createObjects(resp, dataView.getIndexPattern()); if (this._includeEventRateField === true) { @@ -175,4 +184,4 @@ function addEventRateField(aggs: Aggregation[], fields: Field[]) { fields.splice(0, 0, eventRateField); } -export const newJobCapsService = new NewJobCapsService(); +export const newJobCapsService = new NewJobCapsService(ml); diff --git a/x-pack/plugins/ml/public/application/util/index_utils.ts b/x-pack/plugins/ml/public/application/util/index_utils.ts index faa663e579bc..4bca137d4e50 100644 --- a/x-pack/plugins/ml/public/application/util/index_utils.ts +++ b/x-pack/plugins/ml/public/application/util/index_utils.ts @@ -129,6 +129,6 @@ export function timeBasedIndexCheck(dataView: DataView, showNotification = false * Returns true if the data view index pattern contains a : * which means it is cross-cluster */ -export function isCcsIndexPattern(dataViewIndexPattern: string) { - return dataViewIndexPattern.includes(':'); +export function isCcsIndexPattern(indexPattern: string) { + return indexPattern.includes(':'); } diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx index 7186148caf6e..27322086dc01 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/embeddable_swim_lane_container.tsx @@ -79,7 +79,7 @@ export const EmbeddableSwimLaneContainer: FC = ( services, chartWidth, fromPage, - { onRenderComplete, onError, onLoading } + { onError, onLoading } ); useEffect(() => { @@ -171,6 +171,7 @@ export const EmbeddableSwimLaneContainer: FC = ( /> } chartsService={chartsService} + onRenderComplete={onRenderComplete} />
    ); diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts index eace431179da..4e0f491007cd 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.test.ts @@ -22,7 +22,6 @@ describe('useSwimlaneInputResolver', () => { const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const renderCallbacks = { - onRenderComplete: jest.fn(), onLoading: jest.fn(), onError: jest.fn(), }; @@ -113,7 +112,6 @@ describe('useSwimlaneInputResolver', () => { expect(services[2].anomalyTimelineService.loadOverallData).toHaveBeenCalledTimes(1); expect(renderCallbacks.onLoading).toHaveBeenCalledTimes(1); - expect(renderCallbacks.onRenderComplete).toHaveBeenCalledTimes(1); await act(async () => { embeddableInput.next({ @@ -130,7 +128,6 @@ describe('useSwimlaneInputResolver', () => { expect(services[2].anomalyTimelineService.loadOverallData).toHaveBeenCalledTimes(2); expect(renderCallbacks.onLoading).toHaveBeenCalledTimes(2); - expect(renderCallbacks.onRenderComplete).toHaveBeenCalledTimes(2); await act(async () => { embeddableInput.next({ @@ -147,7 +144,6 @@ describe('useSwimlaneInputResolver', () => { expect(services[2].anomalyTimelineService.loadOverallData).toHaveBeenCalledTimes(3); expect(renderCallbacks.onLoading).toHaveBeenCalledTimes(3); - expect(renderCallbacks.onRenderComplete).toHaveBeenCalledTimes(3); }); test('should not complete the observable on error', async () => { diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts index d543ff4cc9bf..8669c3b7bd52 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts +++ b/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/swimlane_input_resolver.ts @@ -50,8 +50,7 @@ export function useSwimlaneInputResolver( services: [CoreStart, MlStartDependencies, AnomalySwimlaneServices], chartWidth: number, fromPage: number, - renderCallbacks: { - onRenderComplete: () => void; + reportingCallbacks: { onLoading: () => void; onError: (error: Error) => void; } @@ -131,7 +130,7 @@ export function useSwimlaneInputResolver( tap(setIsLoading.bind(null, true)), debounceTime(FETCH_RESULTS_DEBOUNCE_MS), tap(() => { - renderCallbacks.onLoading(); + reportingCallbacks.onLoading(); }), switchMap(([explorerJobs, input, bucketInterval, fromPageInput, perPageFromState]) => { if (!explorerJobs) { @@ -246,18 +245,11 @@ export function useSwimlaneInputResolver( useEffect(() => { if (error) { - renderCallbacks.onError(error); + reportingCallbacks.onError(error); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [error]); - useEffect(() => { - if (swimlaneData) { - renderCallbacks.onRenderComplete(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [swimlaneData]); - return [ swimlaneType, swimlaneData, diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx new file mode 100644 index 000000000000..5e52b0f5cd21 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/create_job.tsx @@ -0,0 +1,273 @@ +/* + * 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, { FC, useCallback, useMemo, useState, useEffect } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { + EuiCheckableCard, + EuiTitle, + EuiSpacer, + EuiSwitch, + EuiHorizontalRule, + EuiComboBoxOptionOption, + EuiComboBox, + EuiFormRow, + EuiCallOut, +} from '@elastic/eui'; + +import type { DataViewField, DataView } from '@kbn/data-views-plugin/common'; +import type { TimeRange } from '@kbn/es-query'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { redirectToADJobWizards } from '../../../../application/jobs/new_job/job_from_pattern_analysis/utils'; +import { createFieldOptions } from '../../../../application/jobs/new_job/common/job_creator/util/general'; +import { NewJobCapsService } from '../../../../application/services/new_job_capabilities/new_job_capabilities_service'; +import { + type CategorizationType, + CATEGORIZATION_TYPE, + QuickCategorizationJobCreator, +} from '../../../../application/jobs/new_job/job_from_pattern_analysis'; +import { useMlFromLensKibanaContext } from '../../common/context'; +import { JobDetails, type CreateADJobParams } from '../../common/job_details'; + +interface Props { + dataView: DataView; + field: DataViewField; + query: QueryDslQueryContainer; + timeRange: TimeRange; +} + +export const CreateJob: FC = ({ dataView, field, query, timeRange }) => { + const { + services: { + data, + share, + uiSettings, + mlServices: { mlApiServices }, + dashboardService, + }, + } = useMlFromLensKibanaContext(); + + const [categorizationType, setCategorizationType] = useState( + CATEGORIZATION_TYPE.COUNT + ); + const [enablePerPartitionCategorization, setEnablePerPartitionCategorization] = useState(false); + const [stopOnWarn, setStopOnWarn] = useState(false); + const [categoryFieldOptions, setCategoryFieldsOptions] = useState([]); + const [selectedPartitionFieldOptions, setSelectedPartitionFieldOptions] = useState< + EuiComboBoxOptionOption[] + >([]); + const [formComplete, setFormComplete] = useState(undefined); + + const toggleEnablePerPartitionCategorization = useCallback( + () => setEnablePerPartitionCategorization(!enablePerPartitionCategorization), + [enablePerPartitionCategorization] + ); + + const toggleStopOnWarn = useCallback(() => setStopOnWarn(!stopOnWarn), [stopOnWarn]); + + useMemo(() => { + const newJobCapsService = new NewJobCapsService(mlApiServices); + newJobCapsService.initializeFromDataVIew(dataView).then(() => { + const options: EuiComboBoxOptionOption[] = [ + ...createFieldOptions(newJobCapsService.categoryFields, []), + ].map((o) => ({ + ...o, + })); + setCategoryFieldsOptions(options); + }); + }, [dataView, mlApiServices]); + + const quickJobCreator = useMemo( + () => + new QuickCategorizationJobCreator( + uiSettings, + data.query.timefilter.timefilter, + dashboardService, + data, + mlApiServices + ), + + [dashboardService, data, mlApiServices, uiSettings] + ); + + function createADJobInWizard() { + const partitionField = selectedPartitionFieldOptions.length + ? dataView.getFieldByName(selectedPartitionFieldOptions[0].label) ?? null + : null; + redirectToADJobWizards( + categorizationType, + dataView, + field, + partitionField, + stopOnWarn, + query, + timeRange, + share + ); + } + + useEffect(() => { + setSelectedPartitionFieldOptions([]); + setStopOnWarn(false); + }, [enablePerPartitionCategorization]); + + useEffect(() => { + setFormComplete( + enablePerPartitionCategorization === false || selectedPartitionFieldOptions.length > 0 + ); + }, [enablePerPartitionCategorization, selectedPartitionFieldOptions]); + + async function createADJob({ jobId, bucketSpan, startJob, runInRealTime }: CreateADJobParams) { + const partitionField = selectedPartitionFieldOptions.length + ? dataView.getFieldByName(selectedPartitionFieldOptions[0].label) ?? null + : null; + const result = await quickJobCreator.createAndSaveJob( + categorizationType, + jobId, + bucketSpan, + dataView, + field, + partitionField, + stopOnWarn, + query, + timeRange, + startJob, + runInRealTime + ); + return result; + } + return ( + + <> + + +
    + +
    +
    + + + + } + checked={categorizationType === CATEGORIZATION_TYPE.COUNT} + onChange={() => setCategorizationType(CATEGORIZATION_TYPE.COUNT)} + /> + + + + + +
    + +
    +
    + + + + } + checked={categorizationType === CATEGORIZATION_TYPE.RARE} + onChange={() => setCategorizationType(CATEGORIZATION_TYPE.RARE)} + /> + + + } + /> + + {enablePerPartitionCategorization ? ( + <> + + + + } + /> + + + + + } + > + + + + + + + } + /> + + ) : null} + + + + + +
    + ); +}; diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/flyout.tsx new file mode 100644 index 000000000000..48781b177614 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/flyout.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFlyoutFooter, + EuiFlyoutHeader, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiFlyoutBody, + EuiTitle, + EuiSpacer, + EuiText, +} from '@elastic/eui'; + +import type { DataViewField, DataView } from '@kbn/data-views-plugin/common'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { TimeRange } from '@kbn/es-query'; +import { CreateJob } from './create_job'; + +interface Props { + dataView: DataView; + field: DataViewField; + query: QueryDslQueryContainer; + timeRange: TimeRange; + onClose: () => void; +} + +export const CreateCategorizationJobFlyout: FC = ({ + onClose, + dataView, + field, + query, + timeRange, +}) => { + return ( + <> + + +

    + +

    +
    + + + + +
    + + + + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/index.ts b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/index.ts new file mode 100644 index 000000000000..ab544dc3d55b --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/flyout/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { CreateCategorizationJobFlyout } from './flyout'; diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/index.ts b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/index.ts new file mode 100644 index 000000000000..a156caa5ef57 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { showPatternAnalysisToADJobFlyout } from './show_flyout'; diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/aiops/show_flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/show_flyout.tsx new file mode 100644 index 000000000000..c1fe261cbe92 --- /dev/null +++ b/x-pack/plugins/ml/public/embeddables/job_creation/aiops/show_flyout.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import type { CoreStart } from '@kbn/core/public'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; +import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; +import type { LensPublicStart } from '@kbn/lens-plugin/public'; +import type { DashboardStart } from '@kbn/dashboard-plugin/public'; +import type { DataView, DataViewField } from '@kbn/data-views-plugin/common'; +import type { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { TimeRange } from '@kbn/es-query'; +import { createFlyout, type FlyoutComponentProps } from '../common/create_flyout'; +import { CreateCategorizationJobFlyout } from './flyout'; + +export async function showPatternAnalysisToADJobFlyout( + dataView: DataView, + field: DataViewField, + query: QueryDslQueryContainer, + timeRange: TimeRange, + coreStart: CoreStart, + share: SharePluginStart, + data: DataPublicPluginStart, + dashboardService: DashboardStart, + lens?: LensPublicStart +): Promise { + const Comp: FC = ({ onClose }) => ( + + ); + return createFlyout(Comp, coreStart, share, data, dashboardService, lens); +} diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/lens/context.ts b/x-pack/plugins/ml/public/embeddables/job_creation/common/context.ts similarity index 100% rename from x-pack/plugins/ml/public/embeddables/job_creation/lens/context.ts rename to x-pack/plugins/ml/public/embeddables/job_creation/common/context.ts diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx index 7fd5f9e86fca..b1bc9ec47ba9 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx @@ -14,15 +14,16 @@ import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { CoreStart } from '@kbn/core/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; -import type { MapEmbeddable } from '@kbn/maps-plugin/public'; -import type { Embeddable } from '@kbn/lens-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import { getMlGlobalServices } from '../../../application/app'; +export interface FlyoutComponentProps { + onClose: () => void; +} + export function createFlyout( FlyoutComponent: React.FunctionComponent, - embeddable: MapEmbeddable | Embeddable, coreStart: CoreStart, share: SharePluginStart, data: DataPublicPluginStart, @@ -57,7 +58,6 @@ export function createFlyout( }} > { onFlyoutClose(); resolve(); diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx index e2fff3bd286c..312d75a2a97b 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/common/job_details.tsx @@ -32,6 +32,7 @@ import type { Embeddable } from '@kbn/lens-plugin/public'; import type { MapEmbeddable } from '@kbn/maps-plugin/public'; import { extractErrorMessage } from '@kbn/ml-error-utils'; +import type { TimeRange } from '@kbn/es-query'; import { QuickLensJobCreator } from '../../../application/jobs/new_job/job_from_lens'; import type { LayerResult } from '../../../application/jobs/new_job/job_from_lens'; import type { CreateState } from '../../../application/jobs/new_job/job_from_dashboard'; @@ -40,12 +41,12 @@ import { basicJobValidation } from '../../../../common/util/job_utils'; import { JOB_ID_MAX_LENGTH } from '../../../../common/constants/validation'; import { invalidTimeIntervalMessage } from '../../../application/jobs/new_job/common/job_validator/util'; import { ML_APP_LOCATOR, ML_PAGES } from '../../../../common/constants/locator'; -import { useMlFromLensKibanaContext } from '../lens/context'; +import { useMlFromLensKibanaContext } from './context'; export interface CreateADJobParams { jobId: string; bucketSpan: string; - embeddable: MapEmbeddable | Embeddable; + embeddable: MapEmbeddable | Embeddable | undefined; startJob: boolean; runInRealTime: boolean; } @@ -56,8 +57,10 @@ interface Props { createADJob: (args: CreateADJobParams) => Promise; layer?: LayerResult; layerIndex: number; - embeddable: Embeddable | MapEmbeddable; + embeddable: Embeddable | MapEmbeddable | undefined; + timeRange: TimeRange | undefined; incomingCreateError?: { text: string; errorText: string }; + outerFormComplete?: boolean; } enum STATE { @@ -75,7 +78,9 @@ export const JobDetails: FC = ({ layer, layerIndex, embeddable, + timeRange, incomingCreateError, + outerFormComplete, }) => { const { services: { @@ -121,7 +126,6 @@ export const JobDetails: FC = ({ const viewResults = useCallback( async (type: JOB_TYPE | null) => { - const { timeRange } = embeddable.getInput(); const locator = share.url.locators.get(ML_APP_LOCATOR); if (locator) { const page = startJob @@ -144,7 +148,7 @@ export const JobDetails: FC = ({ application.navigateToUrl(url); } }, - [jobId, embeddable, share, application, startJob] + [share, startJob, jobId, timeRange, application] ); function setStartJobWrapper(start: boolean) { @@ -313,7 +317,8 @@ export const JobDetails: FC = ({ state === STATE.VALIDATING || jobId === '' || jobIdValidationError !== '' || - bucketSpanValidationError !== '' + bucketSpanValidationError !== '' || + outerFormComplete === false } onClick={createJob.bind(null, layerIndex)} size="s" diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/flyout.tsx index 06420c071c22..dc0ab2edd4a1 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/flyout.tsx @@ -23,7 +23,7 @@ import { import { Layer } from './layer'; import type { LayerResult } from '../../../../application/jobs/new_job/job_from_lens'; import { VisualizationExtractor } from '../../../../application/jobs/new_job/job_from_lens'; -import { useMlFromLensKibanaContext } from '../context'; +import { useMlFromLensKibanaContext } from '../../common/context'; interface Props { embeddable: Embeddable; diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx index 0d024bd2d77a..d82ddbf94dd8 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/lens/lens_vis_layer_selection_flyout/layer/compatible_layer.tsx @@ -17,7 +17,7 @@ import { } from '../../../../../application/jobs/new_job/job_from_lens'; import type { LayerResult } from '../../../../../application/jobs/new_job/job_from_lens'; import { JOB_TYPE } from '../../../../../../common/constants/new_job'; -import { useMlFromLensKibanaContext } from '../../context'; +import { useMlFromLensKibanaContext } from '../../../common/context'; import { JobDetails, CreateADJobParams } from '../../../common/job_details'; interface Props { @@ -79,6 +79,7 @@ export const CompatibleLayer: FC = ({ layer, layerIndex, embeddable }) => createADJob={createADJob} createADJobInWizard={createADJobInWizard} embeddable={embeddable} + timeRange={embeddable.getInput().timeRange} layer={layer} layerIndex={layerIndex} > diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/lens/show_flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/lens/show_flyout.tsx index 91e6f6f00186..375588765bd1 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/lens/show_flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/lens/show_flyout.tsx @@ -5,13 +5,14 @@ * 2.0. */ +import React, { FC } from 'react'; import type { Embeddable } from '@kbn/lens-plugin/public'; import type { CoreStart } from '@kbn/core/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { LensPublicStart } from '@kbn/lens-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; -import { createFlyout } from '../common/create_flyout'; +import { createFlyout, type FlyoutComponentProps } from '../common/create_flyout'; import { LensLayerSelectionFlyout } from './lens_vis_layer_selection_flyout'; export async function showLensVisToADJobFlyout( @@ -19,16 +20,11 @@ export async function showLensVisToADJobFlyout( coreStart: CoreStart, share: SharePluginStart, data: DataPublicPluginStart, - lens: LensPublicStart, - dashboardService: DashboardStart + dashboardService: DashboardStart, + lens: LensPublicStart ): Promise { - return createFlyout( - LensLayerSelectionFlyout, - embeddable, - coreStart, - share, - data, - dashboardService, - lens + const Comp: FC = ({ onClose }) => ( + ); + return createFlyout(Comp, coreStart, share, data, dashboardService, lens); } diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx index d4075414e3a9..8f368dc0a82c 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/map/map_vis_layer_selection_flyout/layer/compatible_layer.tsx @@ -25,7 +25,7 @@ import { QuickGeoJobCreator, redirectToGeoJobWizard, } from '../../../../../application/jobs/new_job/job_from_map'; -import { useMlFromLensKibanaContext } from '../../../lens/context'; +import { useMlFromLensKibanaContext } from '../../../common/context'; import { JobDetails, CreateADJobParams } from '../../../common/job_details'; interface DropDownLabel { @@ -147,6 +147,7 @@ export const CompatibleLayer: FC = ({ embeddable, layer, layerIndex }) => createADJob={createGeoJob} createADJobInWizard={createGeoJobInWizard} embeddable={embeddable} + timeRange={embeddable.getInput().timeRange} incomingCreateError={createError} > <> diff --git a/x-pack/plugins/ml/public/embeddables/job_creation/map/show_flyout.tsx b/x-pack/plugins/ml/public/embeddables/job_creation/map/show_flyout.tsx index 5380513f1dc9..293ec69b30db 100644 --- a/x-pack/plugins/ml/public/embeddables/job_creation/map/show_flyout.tsx +++ b/x-pack/plugins/ml/public/embeddables/job_creation/map/show_flyout.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import React, { FC } from 'react'; import type { CoreStart } from '@kbn/core/public'; import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; @@ -12,7 +13,7 @@ import type { MapEmbeddable } from '@kbn/maps-plugin/public'; import type { DashboardStart } from '@kbn/dashboard-plugin/public'; import { GeoJobFlyout } from './flyout'; -import { createFlyout } from '../common/create_flyout'; +import { createFlyout, type FlyoutComponentProps } from '../common/create_flyout'; export async function showMapVisToADJobFlyout( embeddable: MapEmbeddable, @@ -21,5 +22,8 @@ export async function showMapVisToADJobFlyout( data: DataPublicPluginStart, dashboardService: DashboardStart ): Promise { - return createFlyout(GeoJobFlyout, embeddable, coreStart, share, data, dashboardService); + const Comp: FC = ({ onClose }) => ( + + ); + return createFlyout(Comp, coreStart, share, data, dashboardService); } diff --git a/x-pack/plugins/ml/public/locator/ml_locator.ts b/x-pack/plugins/ml/public/locator/ml_locator.ts index e397778315a6..05fe312fd9a4 100644 --- a/x-pack/plugins/ml/public/locator/ml_locator.ts +++ b/x-pack/plugins/ml/public/locator/ml_locator.ts @@ -85,6 +85,7 @@ export class MlLocatorDefinition implements LocatorDefinition { case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED: case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_LENS: case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_MAP: + case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_FROM_PATTERN_ANALYSIS: case ML_PAGES.DATA_VISUALIZER: case ML_PAGES.DATA_VISUALIZER_FILE: case ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER: diff --git a/x-pack/plugins/ml/public/ui_actions/index.ts b/x-pack/plugins/ml/public/ui_actions/index.ts index 4067547e0895..4e756d9d44d5 100644 --- a/x-pack/plugins/ml/public/ui_actions/index.ts +++ b/x-pack/plugins/ml/public/ui_actions/index.ts @@ -8,9 +8,14 @@ import { CoreSetup } from '@kbn/core/public'; import { UiActionsSetup } from '@kbn/ui-actions-plugin/public'; import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; +import { CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER } from '@kbn/ml-ui-actions'; import { createEditSwimlanePanelAction } from './edit_swimlane_panel_action'; import { createOpenInExplorerAction } from './open_in_anomaly_explorer_action'; import { createVisToADJobAction } from './open_vis_in_ml_action'; +import { + createCategorizationADJobAction, + createCategorizationADJobTrigger, +} from './open_create_categorization_job_action'; import { MlPluginStart, MlStartDependencies } from '../plugin'; import { createApplyInfluencerFiltersAction } from './apply_influencer_filters_action'; import { @@ -45,6 +50,7 @@ export function registerMlUiActions( const clearSelectionAction = createClearSelectionAction(core.getStartServices); const editExplorerPanelAction = createEditAnomalyChartsPanelAction(core.getStartServices); const visToAdJobAction = createVisToADJobAction(core.getStartServices); + const categorizationADJobAction = createCategorizationADJobAction(core.getStartServices); // Register actions uiActions.registerAction(editSwimlanePanelAction); @@ -54,6 +60,7 @@ export function registerMlUiActions( uiActions.registerAction(applyTimeRangeSelectionAction); uiActions.registerAction(clearSelectionAction); uiActions.registerAction(editExplorerPanelAction); + uiActions.registerAction(categorizationADJobAction); // Assign triggers uiActions.attachAction(CONTEXT_MENU_TRIGGER, editSwimlanePanelAction.id); @@ -62,6 +69,7 @@ export function registerMlUiActions( uiActions.registerTrigger(swimLaneSelectionTrigger); uiActions.registerTrigger(entityFieldSelectionTrigger); + uiActions.registerTrigger(createCategorizationADJobTrigger); uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, applyInfluencerFiltersAction); uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, applyTimeRangeSelectionAction); @@ -69,4 +77,8 @@ export function registerMlUiActions( uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, clearSelectionAction); uiActions.addTriggerAction(EXPLORER_ENTITY_FIELD_SELECTION_TRIGGER, applyEntityFieldFilterAction); uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, visToAdJobAction); + uiActions.addTriggerAction( + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, + categorizationADJobAction + ); } diff --git a/x-pack/plugins/ml/public/ui_actions/open_create_categorization_job_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_create_categorization_job_action.tsx new file mode 100644 index 000000000000..2855020a201d --- /dev/null +++ b/x-pack/plugins/ml/public/ui_actions/open_create_categorization_job_action.tsx @@ -0,0 +1,70 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import type { Trigger, UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public'; +import { + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION, + CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, + type CreateCategorizationADJobContext, +} from '@kbn/ml-ui-actions'; +import type { MlCoreSetup } from '../plugin'; + +export const createCategorizationADJobTrigger: Trigger = { + id: CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, + title: i18n.translate('xpack.ml.actions.createADJobFromPatternAnalysis', { + defaultMessage: 'Create categorization anomaly detection job', + }), + description: i18n.translate('xpack.ml.actions.createADJobFromPatternAnalysis', { + defaultMessage: 'Create categorization anomaly detection job', + }), +}; + +export function createCategorizationADJobAction( + getStartServices: MlCoreSetup['getStartServices'] +): UiActionsActionDefinition { + return { + id: 'create-ml-categorization-ad-job-action', + type: CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION, + getIconType(context): string { + return 'machineLearningApp'; + }, + getDisplayName: () => + i18n.translate('xpack.ml.actions.createADJobFromPatternAnalysis', { + defaultMessage: 'Create categorization anomaly detection job', + }), + async execute({ dataView, field, query, timeRange }: CreateCategorizationADJobContext) { + if (!dataView) { + throw new Error('Not possible to execute an action without the embeddable context'); + } + + try { + const [{ showPatternAnalysisToADJobFlyout }, [coreStart, { share, data, dashboard }]] = + await Promise.all([import('../embeddables/job_creation/aiops'), getStartServices()]); + + await showPatternAnalysisToADJobFlyout( + dataView, + field, + query, + timeRange, + coreStart, + share, + data, + dashboard + ); + } catch (e) { + return Promise.reject(); + } + }, + async isCompatible({ dataView, field }: CreateCategorizationADJobContext) { + return ( + dataView.timeFieldName !== undefined && + dataView.fields.find((f) => f.name === field.name) !== undefined + ); + }, + }; +} diff --git a/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx b/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx index fb0aa38e44d9..f47df760ea9c 100644 --- a/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx +++ b/x-pack/plugins/ml/public/ui_actions/open_vis_in_ml_action.tsx @@ -39,7 +39,7 @@ export function createVisToADJobAction( if (lens === undefined) { return; } - await showLensVisToADJobFlyout(embeddable, coreStart, share, data, lens, dashboard); + await showLensVisToADJobFlyout(embeddable, coreStart, share, data, dashboard, lens); } else if (isMapEmbeddable(embeddable)) { const [{ showMapVisToADJobFlyout }, [coreStart, { share, data, dashboard }]] = await Promise.all([import('../embeddables/job_creation/map'), getStartServices()]); diff --git a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts b/x-pack/plugins/ml/server/models/data_frame_analytics/data_view_handler.ts similarity index 93% rename from x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts rename to x-pack/plugins/ml/server/models/data_frame_analytics/data_view_handler.ts index fc07c69d8dc7..97ec5cbf9766 100644 --- a/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts +++ b/x-pack/plugins/ml/server/models/data_frame_analytics/data_view_handler.ts @@ -9,7 +9,7 @@ import { DataViewsService } from '@kbn/data-views-plugin/common'; export class DataViewHandler { constructor(private dataViewService: DataViewsService) {} - // returns a id based on an index pattern name + // returns a id based on an data view name async getDataViewId(indexName: string) { const dv = (await this.dataViewService.find(indexName)).find( ({ title }) => title === indexName diff --git a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts index 302a8b2c89bb..129ab0f98702 100644 --- a/x-pack/plugins/ml/server/routes/data_frame_analytics.ts +++ b/x-pack/plugins/ml/server/routes/data_frame_analytics.ts @@ -18,35 +18,35 @@ import { wrapError } from '../client/error_wrapper'; import { analyticsAuditMessagesProvider } from '../models/data_frame_analytics/analytics_audit_messages'; import type { RouteInitialization } from '../types'; import { - dataAnalyticsJobConfigSchema, - dataAnalyticsJobUpdateSchema, - dataAnalyticsEvaluateSchema, - dataAnalyticsExplainSchema, - analyticsIdSchema, - analyticsMapQuerySchema, + dataFrameAnalyticsJobConfigSchema, + dataFrameAnalyticsJobUpdateSchema, + dataFrameAnalyticsEvaluateSchema, + dataFrameAnalyticsExplainSchema, + dataFrameAnalyticsIdSchema, + dataFrameAnalyticsMapQuerySchema, stopsDataFrameAnalyticsJobQuerySchema, deleteDataFrameAnalyticsJobSchema, - jobsExistSchema, - analyticsQuerySchema, - analyticsNewJobCapsParamsSchema, - analyticsNewJobCapsQuerySchema, -} from './schemas/data_analytics_schema'; + dataFrameAnalyticsJobsExistSchema, + dataFrameAnalyticsQuerySchema, + dataFrameAnalyticsNewJobCapsParamsSchema, + dataFrameAnalyticsNewJobCapsQuerySchema, +} from './schemas/data_frame_analytics_schema'; import type { ExtendAnalyticsMapArgs } from '../models/data_frame_analytics/types'; -import { DataViewHandler } from '../models/data_frame_analytics/index_patterns'; +import { DataViewHandler } from '../models/data_frame_analytics/data_view_handler'; import { AnalyticsManager } from '../models/data_frame_analytics/analytics_manager'; import { validateAnalyticsJob } from '../models/data_frame_analytics/validation'; import { fieldServiceProvider } from '../models/job_service/new_job_caps/field_service'; import { getAuthorizationHeader } from '../lib/request_authorization'; import type { MlClient } from '../lib/ml_client'; -function getDataViewId(dataViewsService: DataViewsService, patternName: string) { +async function getDataViewId(dataViewsService: DataViewsService, patternName: string) { const iph = new DataViewHandler(dataViewsService); - return iph.getDataViewId(patternName); + return await iph.getDataViewId(patternName); } -function deleteDestDataViewById(dataViewsService: DataViewsService, dataViewId: string) { +async function deleteDestDataViewById(dataViewsService: DataViewsService, dataViewId: string) { const iph = new DataViewHandler(dataViewsService); - return iph.deleteDataViewById(dataViewId); + return await iph.deleteDataViewById(dataViewId); } function getExtendedMap( @@ -144,7 +144,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - query: analyticsQuerySchema, + query: dataFrameAnalyticsQuerySchema, }, }, }, @@ -185,8 +185,8 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, - query: analyticsQuerySchema, + params: dataFrameAnalyticsIdSchema, + query: dataFrameAnalyticsQuerySchema, }, }, }, @@ -262,7 +262,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, + params: dataFrameAnalyticsIdSchema, }, }, }, @@ -305,8 +305,8 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, - body: dataAnalyticsJobConfigSchema, + params: dataFrameAnalyticsIdSchema, + body: dataFrameAnalyticsJobConfigSchema, }, }, }, @@ -352,7 +352,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - body: dataAnalyticsEvaluateSchema, + body: dataFrameAnalyticsEvaluateSchema, }, }, }, @@ -397,7 +397,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - body: dataAnalyticsExplainSchema, + body: dataFrameAnalyticsExplainSchema, }, }, }, @@ -440,7 +440,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, + params: dataFrameAnalyticsIdSchema, query: deleteDataFrameAnalyticsJobSchema, }, }, @@ -449,11 +449,11 @@ export function dataFrameAnalyticsRoutes( async ({ mlClient, client, request, response, getDataViewsService }) => { try { const { analyticsId } = request.params; - const { deleteDestIndex, deleteDestIndexPattern } = request.query; + const { deleteDestIndex, deleteDestDataView } = request.query; let destinationIndex: string | undefined; const analyticsJobDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; const destIndexDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false }; - const destIndexPatternDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { + const destDataViewDeleted: DeleteDataFrameAnalyticsWithIndexStatus = { success: false, }; @@ -473,7 +473,7 @@ export function dataFrameAnalyticsRoutes( return response.customError(wrapError(e)); } - if (deleteDestIndex || deleteDestIndexPattern) { + if (deleteDestIndex || deleteDestDataView) { // If user checks box to delete the destinationIndex associated with the job if (destinationIndex && deleteDestIndex) { // Verify if user has privilege to delete the destination index @@ -494,16 +494,16 @@ export function dataFrameAnalyticsRoutes( } // Delete the index pattern if there's an index pattern that matches the name of dest index - if (destinationIndex && deleteDestIndexPattern) { + if (destinationIndex && deleteDestDataView) { try { const dataViewsService = await getDataViewsService(); const dataViewId = await getDataViewId(dataViewsService, destinationIndex); if (dataViewId) { await deleteDestDataViewById(dataViewsService, dataViewId); } - destIndexPatternDeleted.success = true; + destDataViewDeleted.success = true; } catch (deleteDestIndexPatternError) { - destIndexPatternDeleted.error = deleteDestIndexPatternError; + destDataViewDeleted.error = deleteDestIndexPatternError; } } } @@ -521,7 +521,7 @@ export function dataFrameAnalyticsRoutes( const results = { analyticsJobDeleted, destIndexDeleted, - destIndexPatternDeleted, + destDataViewDeleted, }; return response.ok({ body: results, @@ -555,7 +555,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, + params: dataFrameAnalyticsIdSchema, }, }, }, @@ -597,7 +597,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, + params: dataFrameAnalyticsIdSchema, query: stopsDataFrameAnalyticsJobQuerySchema, }, }, @@ -640,8 +640,8 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, - body: dataAnalyticsJobUpdateSchema, + params: dataFrameAnalyticsIdSchema, + body: dataFrameAnalyticsJobUpdateSchema, }, }, }, @@ -686,7 +686,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, + params: dataFrameAnalyticsIdSchema, }, }, }, @@ -728,7 +728,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - body: jobsExistSchema, + body: dataFrameAnalyticsJobsExistSchema, }, }, }, @@ -785,8 +785,8 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsIdSchema, - query: analyticsMapQuerySchema, + params: dataFrameAnalyticsIdSchema, + query: dataFrameAnalyticsMapQuerySchema, }, }, }, @@ -851,8 +851,8 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - params: analyticsNewJobCapsParamsSchema, - query: analyticsNewJobCapsQuerySchema, + params: dataFrameAnalyticsNewJobCapsParamsSchema, + query: dataFrameAnalyticsNewJobCapsQuerySchema, }, }, }, @@ -906,7 +906,7 @@ export function dataFrameAnalyticsRoutes( version: '1', validate: { request: { - body: dataAnalyticsJobConfigSchema, + body: dataFrameAnalyticsJobConfigSchema, }, }, }, diff --git a/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts b/x-pack/plugins/ml/server/routes/schemas/data_frame_analytics_schema.ts similarity index 80% rename from x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts rename to x-pack/plugins/ml/server/routes/schemas/data_frame_analytics_schema.ts index 7b67a56fe485..1026e425c20c 100644 --- a/x-pack/plugins/ml/server/routes/schemas/data_analytics_schema.ts +++ b/x-pack/plugins/ml/server/routes/schemas/data_frame_analytics_schema.ts @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { runtimeMappingsSchema } from './runtime_mappings_schema'; -export const dataAnalyticsJobConfigSchema = schema.object({ +export const dataFrameAnalyticsJobConfigSchema = schema.object({ description: schema.maybe(schema.string()), _meta: schema.maybe(schema.object({}, { unknowns: 'allow' })), dest: schema.object({ @@ -35,7 +35,7 @@ export const dataAnalyticsJobConfigSchema = schema.object({ max_num_threads: schema.maybe(schema.number()), }); -export const dataAnalyticsEvaluateSchema = schema.object({ +export const dataFrameAnalyticsEvaluateSchema = schema.object({ index: schema.string(), query: schema.maybe(schema.any()), evaluation: schema.maybe( @@ -47,7 +47,7 @@ export const dataAnalyticsEvaluateSchema = schema.object({ ), }); -export const dataAnalyticsExplainSchema = schema.object({ +export const dataFrameAnalyticsExplainSchema = schema.object({ description: schema.maybe(schema.string()), dest: schema.maybe(schema.any()), /** Source */ @@ -63,14 +63,14 @@ export const dataAnalyticsExplainSchema = schema.object({ _meta: schema.maybe(schema.object({}, { unknowns: 'allow' })), }); -export const analyticsIdSchema = schema.object({ +export const dataFrameAnalyticsIdSchema = schema.object({ /** * Analytics ID */ analyticsId: schema.string(), }); -export const analyticsQuerySchema = schema.object({ +export const dataFrameAnalyticsQuerySchema = schema.object({ /** * Analytics Query */ @@ -83,10 +83,10 @@ export const deleteDataFrameAnalyticsJobSchema = schema.object({ * Analytics Destination Index */ deleteDestIndex: schema.maybe(schema.boolean()), - deleteDestIndexPattern: schema.maybe(schema.boolean()), + deleteDestDataView: schema.maybe(schema.boolean()), }); -export const dataAnalyticsJobUpdateSchema = schema.object({ +export const dataFrameAnalyticsJobUpdateSchema = schema.object({ description: schema.maybe(schema.string()), model_memory_limit: schema.maybe(schema.string()), allow_lazy_start: schema.maybe(schema.boolean()), @@ -98,17 +98,19 @@ export const stopsDataFrameAnalyticsJobQuerySchema = schema.object({ force: schema.maybe(schema.boolean()), }); -export const jobsExistSchema = schema.object({ +export const dataFrameAnalyticsJobsExistSchema = schema.object({ analyticsIds: schema.arrayOf(schema.string()), allSpaces: schema.maybe(schema.boolean()), }); -export const analyticsMapQuerySchema = schema.maybe( +export const dataFrameAnalyticsMapQuerySchema = schema.maybe( schema.object({ treatAsRoot: schema.maybe(schema.any()), type: schema.maybe(schema.string()) }) ); -export const analyticsNewJobCapsParamsSchema = schema.object({ indexPattern: schema.string() }); +export const dataFrameAnalyticsNewJobCapsParamsSchema = schema.object({ + indexPattern: schema.string(), +}); -export const analyticsNewJobCapsQuerySchema = schema.maybe( +export const dataFrameAnalyticsNewJobCapsQuerySchema = schema.maybe( schema.object({ rollup: schema.maybe(schema.string()) }) ); diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index 8095411f911e..34cbaf755c1e 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -29,9 +29,9 @@ import { createIngestPipelineSchema, modelDownloadsQuery, } from './schemas/inference_schema'; -import type { +import { PipelineDefinition, - TrainedModelConfigResponse, + type TrainedModelConfigResponse, } from '../../common/types/trained_models'; import { mlLog } from '../lib/log'; import { forceQuerySchema } from './schemas/anomaly_detectors_schema'; @@ -39,10 +39,9 @@ import { modelsProvider } from '../models/model_management'; export const DEFAULT_TRAINED_MODELS_PAGE_SIZE = 10000; -export function filterForEnabledFeatureModels( - models: TrainedModelConfigResponse[] | estypes.MlTrainedModelConfig[], - enabledFeatures: MlFeatures -) { +export function filterForEnabledFeatureModels< + T extends TrainedModelConfigResponse | estypes.MlTrainedModelConfig +>(models: T[], enabledFeatures: MlFeatures) { let filteredModels = models; if (enabledFeatures.nlp === false) { filteredModels = filteredModels.filter((m) => m.model_type === 'tree_ensemble'); @@ -191,10 +190,38 @@ export function trainedModelsRoutes( mlLog.debug(e); } - const body = filterForEnabledFeatureModels(result, getEnabledFeatures()); + const filteredModels = filterForEnabledFeatureModels(result, getEnabledFeatures()); + + try { + const jobIds = filteredModels + .map((model) => { + const id = model.metadata?.analytics_config?.id; + if (id) { + return `${id}*`; + } + }) + .filter((id) => id !== undefined); + + if (jobIds.length) { + const { data_frame_analytics: jobs } = await mlClient.getDataFrameAnalytics({ + id: jobIds.join(','), + allow_no_match: true, + }); + + filteredModels.forEach((model) => { + const dfaId = model?.metadata?.analytics_config?.id; + if (dfaId !== undefined) { + // if this is a dfa model, set origin_job_exists + model.origin_job_exists = jobs.find((job) => job.id === dfaId) !== undefined; + } + }); + } + } catch (e) { + // Swallow error to prevent blocking trained models result + } return response.ok({ - body, + body: filteredModels, }); } catch (e) { return response.customError(wrapError(e)); diff --git a/x-pack/plugins/ml/tsconfig.json b/x-pack/plugins/ml/tsconfig.json index cca832eee042..846825569da6 100644 --- a/x-pack/plugins/ml/tsconfig.json +++ b/x-pack/plugins/ml/tsconfig.json @@ -96,6 +96,7 @@ "@kbn/ml-runtime-field-utils", "@kbn/ml-date-utils", "@kbn/ml-category-validator", + "@kbn/ml-ui-actions", "@kbn/deeplinks-ml", "@kbn/core-notifications-browser-mocks", "@kbn/unified-field-list", diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/types.ts b/x-pack/plugins/observability/common/custom_threshold_rule/types.ts index 40d569152d1a..7668e19dc390 100644 --- a/x-pack/plugins/observability/common/custom_threshold_rule/types.ts +++ b/x-pack/plugins/observability/common/custom_threshold_rule/types.ts @@ -8,7 +8,6 @@ import * as rt from 'io-ts'; import { SerializedSearchSourceFields } from '@kbn/data-plugin/common'; import { TimeUnitChar } from '../utils/formatters/duration'; -import { CUSTOM_AGGREGATOR } from './constants'; export const ThresholdFormatterTypeRT = rt.keyof({ abbreviatedNumber: null, @@ -84,7 +83,6 @@ export interface CustomThresholdExpressionMetric { } export interface CustomMetricExpressionParams extends BaseMetricExpressionParams { - aggType: typeof CUSTOM_AGGREGATOR; metrics: CustomThresholdExpressionMetric[]; equation?: string; label?: string; diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.json b/x-pack/plugins/observability/docs/openapi/slo/bundled.json index b4f52b032a9f..ff366afc2ff1 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.json +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.json @@ -753,7 +753,8 @@ "apiKeyAuth": { "type": "apiKey", "in": "header", - "name": "ApiKey" + "name": "Authorization", + "description": "e.g. Authorization: ApiKey base64AccessApiKey" } }, "parameters": { diff --git a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml index 8efdbd9dfe2c..5aa20726b6a0 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/bundled.yaml @@ -455,7 +455,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' parameters: kbn_xsrf: schema: diff --git a/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml b/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml index 687fd94f006a..910f795aa40a 100644 --- a/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml +++ b/x-pack/plugins/observability/docs/openapi/slo/entrypoint.yaml @@ -35,7 +35,8 @@ components: apiKeyAuth: type: apiKey in: header - name: ApiKey + name: Authorization + description: 'e.g. Authorization: ApiKey base64AccessApiKey' security: - basicAuth: [] - apiKeyAuth: [] diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/__snapshots__/alert_details_app_section.test.tsx.snap b/x-pack/plugins/observability/public/components/custom_threshold/components/__snapshots__/alert_details_app_section.test.tsx.snap index 2e1219343572..0446f2fe1d4a 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/__snapshots__/alert_details_app_section.test.tsx.snap +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/__snapshots__/alert_details_app_section.test.tsx.snap @@ -22,7 +22,6 @@ Array [ "title": "unknown-index", }, "expression": Object { - "aggType": "custom", "comparator": ">", "metrics": Array [ Object { diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section.tsx index a5a029d764a8..deebe5a6cd4c 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/alert_details_app_section.tsx @@ -134,7 +134,7 @@ export default function AlertDetailsAppSection({ -

    {criterion.aggType.toUpperCase()}

    +

    {criterion.label || 'CUSTOM'}

    = { expression: { - aggType: CUSTOM_AGGREGATOR, metrics: [ { name: 'A', @@ -120,7 +118,6 @@ CustomEquationEditorDefault.args = { CustomEquationEditorWithEquationErrors.args = { ...BASE_ARGS, expression: { - aggType: CUSTOM_AGGREGATOR, equation: 'Math.round(A / B)', metrics: [ { name: 'A', aggType: Aggregators.AVERAGE, field: 'system.cpu.user.pct' }, diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/custom_equation_editor.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/custom_equation_editor.tsx index 164db3bac168..e15248d72c49 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/custom_equation_editor.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/custom_equation_editor.tsx @@ -22,6 +22,7 @@ import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public'; import { FormattedMessage } from '@kbn/i18n-react'; import { DataViewBase } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; +import { adjustThresholdBasedOnFormat } from '../../helpers/adjust_threshold_based_on_format'; import { Aggregators, CustomThresholdExpressionMetric, @@ -71,7 +72,12 @@ export function CustomEquationEditor({ const currentVars = previous?.map((m) => m.name) ?? []; const name = first(xor(VAR_NAMES, currentVars))!; const nextMetrics = [...(previous || []), { ...NEW_METRIC, name }]; - debouncedOnChange({ ...expression, metrics: nextMetrics, equation }); + debouncedOnChange({ + ...expression, + metrics: nextMetrics, + equation, + threshold: adjustThresholdBasedOnFormat(previous, nextMetrics, expression.threshold), + }); return nextMetrics; }); }, [debouncedOnChange, equation, expression]); @@ -81,7 +87,12 @@ export function CustomEquationEditor({ setCustomMetrics((previous) => { const nextMetrics = previous?.filter((row) => row.name !== name) ?? [NEW_METRIC]; const finalMetrics = (nextMetrics.length && nextMetrics) || [NEW_METRIC]; - debouncedOnChange({ ...expression, metrics: finalMetrics, equation }); + debouncedOnChange({ + ...expression, + metrics: finalMetrics, + equation, + threshold: adjustThresholdBasedOnFormat(previous, nextMetrics, expression.threshold), + }); return finalMetrics; }); }, @@ -92,7 +103,12 @@ export function CustomEquationEditor({ (metric: CustomThresholdExpressionMetric) => { setCustomMetrics((previous) => { const nextMetrics = previous?.map((m) => (m.name === metric.name ? metric : m)); - debouncedOnChange({ ...expression, metrics: nextMetrics, equation }); + debouncedOnChange({ + ...expression, + metrics: nextMetrics, + equation, + threshold: adjustThresholdBasedOnFormat(previous, nextMetrics, expression.threshold), + }); return nextMetrics; }); }, diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_controls.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_controls.tsx index d43c09d7c378..305be75390df 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_controls.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_controls.tsx @@ -5,7 +5,7 @@ * 2.0. */ import React from 'react'; -import { EuiFlexItem, EuiButtonIcon } from '@elastic/eui'; +import { EuiButtonIcon } from '@elastic/eui'; import { DELETE_LABEL } from '../../i18n_strings'; interface MetricRowControlProps { @@ -15,19 +15,16 @@ interface MetricRowControlProps { export function MetricRowControls({ onDelete, disableDelete }: MetricRowControlProps) { return ( - <> - - - - + ); } diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_with_agg.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_with_agg.tsx index 51c4713fef26..a00a086ef552 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_with_agg.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/custom_equation/metric_row_with_agg.tsx @@ -112,117 +112,123 @@ export function MetricRowWithAgg({ const isFieldInvalid = get(errors, ['metrics', name, 'field']) != null || !field; return ( - <> - - - - { - setAggTypePopoverOpen(true); - }} - isInvalid={aggType !== Aggregators.COUNT && !field} - /> - - } - isOpen={aggTypePopoverOpen} - closePopover={() => { - setAggTypePopoverOpen(false); - }} - display="block" - ownFocus - anchorPosition={'downLeft'} - repositionOnScroll - > -
    - setAggTypePopoverOpen(false)}> - - + + + + + {i18n.translate( + 'xpack.observability.customThreshold.rule.alertFlyout.customEquationEditor.aggregationLabel', + { defaultMessage: 'Aggregation {name}', values: { name } } + )} + + {!disableDelete && ( + + + + )} + + } + > + { + setAggTypePopoverOpen(true); + }} + isInvalid={aggType !== Aggregators.COUNT && !field} + /> + + } + isOpen={aggTypePopoverOpen} + closePopover={() => { + setAggTypePopoverOpen(false); + }} + display="block" + ownFocus + anchorPosition={'downLeft'} + repositionOnScroll + > +
    + setAggTypePopoverOpen(false)}> + + - - + + + + { + handleAggChange(e.target.value); + }} + options={Object.values(aggregationTypes).map(({ text, value }) => { + return { + text, + value, + }; + })} + isInvalid={isAggInvalid} + /> + + + + {aggType === Aggregators.COUNT ? ( + + + + ) : ( - { - handleAggChange(e.target.value); - }} - options={Object.values(aggregationTypes).map(({ text, value }) => { - return { - text, - value, - }; - })} - isInvalid={isAggInvalid} + isInvalid={isFieldInvalid} + singleSelection={{ asPlainText: true }} + options={fieldOptions} + selectedOptions={field ? [{ label: field }] : []} + onChange={handleFieldChange} /> - - - {aggType === Aggregators.COUNT ? ( - - - - ) : ( - - - - )} - - -
    - - - - - + )} + + +
    +
    +
    +
    ); } diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.test.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.test.tsx index 956391a3f29b..5af6cae385d7 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.test.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_chart.test.tsx @@ -12,7 +12,6 @@ import { DataViewBase } from '@kbn/es-query'; import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; import React, { ReactElement } from 'react'; import { act } from 'react-dom/test-utils'; -import { CUSTOM_AGGREGATOR } from '../../../../common/custom_threshold_rule/constants'; import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types'; import { MetricExpression } from '../types'; import { ExpressionChart } from './expression_chart'; @@ -77,7 +76,6 @@ describe('ExpressionChart', () => { it('should display no data message', async () => { const expression: MetricExpression = { - aggType: CUSTOM_AGGREGATOR, metrics: [ { name: 'A', diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.test.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.test.tsx index 8b0a4de92bd7..2bdd1f2def08 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.test.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.test.tsx @@ -9,7 +9,6 @@ import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; import React from 'react'; import { act } from 'react-dom/test-utils'; -import { CUSTOM_AGGREGATOR } from '../../../../common/custom_threshold_rule/constants'; import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types'; import { MetricExpression } from '../types'; import { ExpressionRow } from './expression_row'; @@ -18,6 +17,7 @@ describe('ExpressionRow', () => { async function setup(expression: MetricExpression) { const wrapper = mountWithIntl( Condition} canDelete={false} fields={[ { @@ -57,7 +57,6 @@ describe('ExpressionRow', () => { it('should display thresholds as a percentage for pct metrics', async () => { const expression: MetricExpression = { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -83,7 +82,6 @@ describe('ExpressionRow', () => { it('should display thresholds as a decimal for all other metrics', async () => { const expression = { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.tsx index 0f53594bd49e..6b0643791596 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/expression_row.tsx @@ -12,9 +12,10 @@ import { EuiFlexItem, EuiFormRow, EuiSpacer, + EuiTitle, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState, ReactElement } from 'react'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; import { AggregationType, @@ -47,6 +48,7 @@ const customComparators = { }; interface ExpressionRowProps { + title: ReactElement; fields: DataViewFieldBase[]; expressionId: number; expression: MetricExpression; @@ -77,6 +79,7 @@ export const ExpressionRow: React.FC = (props) => { remove, fields, canDelete, + title, } = props; const { metrics, comparator = Comparator.GT, threshold = [] } = expression; @@ -146,6 +149,29 @@ export const ExpressionRow: React.FC = (props) => { ); return ( <> + + + +
    {title}
    +
    +
    + {canDelete && ( + + remove(expressionId)} + /> + + )} +
    @@ -178,25 +204,8 @@ export const ExpressionRow: React.FC = (props) => { - {canDelete && ( - - remove(expressionId)} - /> - - )} {children} - ); }; diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.test.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.test.tsx index 9226da0ca237..3adc5975e91a 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.test.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.test.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; import { DataView } from '@kbn/data-views-plugin/common'; import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers'; -import { CUSTOM_AGGREGATOR } from '../../../../../common/custom_threshold_rule/constants'; import { Comparator, Aggregators } from '../../../../../common/custom_threshold_rule/types'; import { useKibana } from '../../../../utils/kibana_react'; import { kibanaStartMock } from '../../../../utils/kibana_react.mock'; @@ -55,7 +54,6 @@ describe('Preview chart', () => { it('should display no data message', async () => { const expression: MetricExpression = { - aggType: CUSTOM_AGGREGATOR, metrics: [ { name: 'A', diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.tsx index d5a8b763ca7b..23d27a554a77 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/preview_chart/preview_chart.tsx @@ -218,12 +218,7 @@ export function PreviewChart({ decimals: isPercent ? 0 : 2, }, }, - filter: { - language: 'kuery', - query: filterQuery || '', - }, }; - const xYDataLayerOptions: XYLayerOptions = { buckets: { type: 'date_histogram', @@ -252,7 +247,6 @@ export function PreviewChart({ value: layer.value, label: layer.label, format: layer.format, - filter: layer.filter, })), options: xYDataLayerOptions, }); @@ -333,6 +327,10 @@ export function PreviewChart({ timeRange={{ from: `now-${timeSize * 20}${timeUnit}`, to: 'now' }} attributes={attributes} disableTriggers={true} + query={{ + language: 'kuery', + query: filterQuery || '', + }} />
    ); diff --git a/x-pack/plugins/observability/public/components/custom_threshold/components/validation.tsx b/x-pack/plugins/observability/public/components/custom_threshold/components/validation.tsx index f360b415fa1b..2144757216fb 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/components/validation.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/components/validation.tsx @@ -27,17 +27,12 @@ export function validateCustomThreshold({ const validationResult = { errors: {} }; const errors: { [id: string]: { - aggField: string[]; timeSizeUnit: string[]; timeWindowSize: string[]; critical: { threshold0: string[]; threshold1: string[]; }; - warning: { - threshold0: string[]; - threshold1: string[]; - }; metricsError?: string; metrics: Record; equation?: string; @@ -91,23 +86,9 @@ export function validateCustomThreshold({ threshold0: [], threshold1: [], }, - warning: { - threshold0: [], - threshold1: [], - }, metric: [], metrics: {}, }; - if (!c.aggType) { - errors[id].aggField.push( - i18n.translate( - 'xpack.observability.customThreshold.rule.alertFlyout.error.aggregationRequired', - { - defaultMessage: 'Aggregation is required.', - } - ) - ); - } if (!c.threshold || !c.threshold.length) { errors[id].critical.threshold0.push( @@ -120,8 +101,30 @@ export function validateCustomThreshold({ ); } - if (c.warningThreshold && !c.warningThreshold.length) { - errors[id].warning.threshold0.push( + // The Threshold component returns an empty array with a length ([empty]) because it's using delete newThreshold[i]. + // We need to use [...c.threshold] to convert it to an array with an undefined value ([undefined]) so we can test each element. + const { comparator, threshold } = { comparator: c.comparator, threshold: c.threshold } as { + comparator?: Comparator; + threshold?: number[]; + }; + if (threshold && threshold.length && ![...threshold].every(isNumber)) { + [...threshold].forEach((v, i) => { + if (!isNumber(v)) { + const key = i === 0 ? 'threshold0' : 'threshold1'; + errors[id].critical[key].push( + i18n.translate( + 'xpack.observability.customThreshold.rule.alertFlyout.error.thresholdTypeRequired', + { + defaultMessage: 'Thresholds must contain a valid number.', + } + ) + ); + } + }); + } + + if (comparator === Comparator.BETWEEN && (!threshold || threshold.length < 2)) { + errors[id].critical.threshold1.push( i18n.translate( 'xpack.observability.customThreshold.rule.alertFlyout.error.thresholdRequired', { @@ -131,45 +134,6 @@ export function validateCustomThreshold({ ); } - for (const props of [ - { comparator: c.comparator, threshold: c.threshold, type: 'critical' }, - { comparator: c.warningComparator, threshold: c.warningThreshold, type: 'warning' }, - ]) { - // The Threshold component returns an empty array with a length ([empty]) because it's using delete newThreshold[i]. - // We need to use [...c.threshold] to convert it to an array with an undefined value ([undefined]) so we can test each element. - const { comparator, threshold, type } = props as { - comparator?: Comparator; - threshold?: number[]; - type: 'critical' | 'warning'; - }; - if (threshold && threshold.length && ![...threshold].every(isNumber)) { - [...threshold].forEach((v, i) => { - if (!isNumber(v)) { - const key = i === 0 ? 'threshold0' : 'threshold1'; - errors[id][type][key].push( - i18n.translate( - 'xpack.observability.customThreshold.rule.alertFlyout.error.thresholdTypeRequired', - { - defaultMessage: 'Thresholds must contain a valid number.', - } - ) - ); - } - }); - } - - if (comparator === Comparator.BETWEEN && (!threshold || threshold.length < 2)) { - errors[id][type].threshold1.push( - i18n.translate( - 'xpack.observability.customThreshold.rule.alertFlyout.error.thresholdRequired', - { - defaultMessage: 'Threshold is required.', - } - ) - ); - } - } - if (!c.timeSize) { errors[id].timeWindowSize.push( i18n.translate('xpack.observability.customThreshold.rule.alertFlyout.error.timeRequred', { diff --git a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.test.tsx b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.test.tsx index 78fa6c324442..0f1742469c31 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.test.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.test.tsx @@ -92,10 +92,9 @@ describe('Expression', () => { }, ], comparator: Comparator.GT, - threshold: [1000], + threshold: [100], timeSize: 1, timeUnit: 'm', - aggType: 'custom', }, ]); }); diff --git a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx index 2c5f7438b048..539f8fbf4f58 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx +++ b/x-pack/plugins/observability/public/components/custom_threshold/custom_threshold_rule_expression.tsx @@ -14,6 +14,7 @@ import { EuiEmptyPrompt, EuiFormErrorText, EuiFormRow, + EuiHorizontalRule, EuiIcon, EuiLink, EuiLoadingSpinner, @@ -36,7 +37,6 @@ import { } from '@kbn/triggers-actions-ui-plugin/public'; import { useKibana } from '../../utils/kibana_react'; -import { CUSTOM_AGGREGATOR } from '../../../common/custom_threshold_rule/constants'; import { Aggregators, Comparator } from '../../../common/custom_threshold_rule/types'; import { TimeUnitChar } from '../../../common/utils/formatters/duration'; import { AlertContextMeta, AlertParams, MetricExpression } from './types'; @@ -52,7 +52,6 @@ type Props = Omit< >; export const defaultExpression: MetricExpression = { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -60,7 +59,7 @@ export const defaultExpression: MetricExpression = { aggType: Aggregators.COUNT, }, ], - threshold: [1000], + threshold: [100], timeSize: 1, timeUnit: 'm', }; @@ -202,11 +201,8 @@ export default function Expressions(props: Props) { const removeExpression = useCallback( (id: number) => { - const ruleCriteria = ruleParams.criteria?.slice() || []; - if (ruleCriteria.length > 1) { - ruleCriteria.splice(id, 1); - setRuleParams('criteria', ruleCriteria); - } + const ruleCriteria = ruleParams.criteria?.filter((_, index) => index !== id) || []; + setRuleParams('criteria', ruleCriteria); }, [setRuleParams, ruleParams.criteria] ); @@ -375,30 +371,11 @@ export default function Expressions(props: Props) { )} - -
    - -
    -
    {ruleParams.criteria && ruleParams.criteria.map((e, idx) => { return (
    - {/* index has semantic meaning, we show the condition title starting from the 2nd one */} - {idx >= 1 && ( - -
    - -
    -
    - )} + {idx > 0 && } 1) || false} fields={derivedIndexPattern.fields} @@ -410,6 +387,20 @@ export default function Expressions(props: Props) { errors={(errors[idx] as IErrorObject) || emptyError} expression={e || {}} dataView={derivedIndexPattern} + title={ + ruleParams.criteria.length === 1 ? ( + + ) : ( + + ) + } > { + test('previous: nonPercent, next: percent -> threshold / 100', () => { + const previous: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + aggType: Aggregators.COUNT, + }, + ]; + const next: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + field: 'system.cpu.system.pct', + aggType: Aggregators.AVERAGE, + }, + ]; + const threshold: number[] = [100]; + const expectedThreshold: number[] = [1]; + + expect(adjustThresholdBasedOnFormat(previous, next, threshold)).toEqual(expectedThreshold); + }); + + test('previous: percent, next: nonPercent -> threshold * 100', () => { + const previous: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + field: 'system.cpu.system.pct', + aggType: Aggregators.AVERAGE, + }, + ]; + const next: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + aggType: Aggregators.COUNT, + }, + ]; + const threshold: number[] = [1]; + const expectedThreshold: number[] = [100]; + + expect(adjustThresholdBasedOnFormat(previous, next, threshold)).toEqual(expectedThreshold); + }); + + test('previous: percent, next: percent -> no threshold change', () => { + const previous: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + field: 'system.cpu.system.pct', + aggType: Aggregators.AVERAGE, + }, + ]; + const next: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + field: 'system.cpu.total.norm.pct', + aggType: Aggregators.AVERAGE, + }, + ]; + const threshold: number[] = [1]; + + expect(adjustThresholdBasedOnFormat(previous, next, threshold)).toEqual(threshold); + }); + + test('previous: nonPercent, next: nonPercent -> threshold * 100', () => { + const previous: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + field: 'host.disk.read.bytes', + aggType: Aggregators.AVERAGE, + }, + ]; + const next: CustomThresholdExpressionMetric[] = [ + { + name: 'A', + aggType: Aggregators.COUNT, + }, + ]; + const threshold: number[] = [100]; + + expect(adjustThresholdBasedOnFormat(previous, next, threshold)).toEqual(threshold); + }); +}); diff --git a/x-pack/plugins/observability/public/components/custom_threshold/helpers/adjust_threshold_based_on_format.ts b/x-pack/plugins/observability/public/components/custom_threshold/helpers/adjust_threshold_based_on_format.ts new file mode 100644 index 000000000000..ba4976684e38 --- /dev/null +++ b/x-pack/plugins/observability/public/components/custom_threshold/helpers/adjust_threshold_based_on_format.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 { CustomThresholdExpressionMetric } from '../../../../common/custom_threshold_rule/types'; +import { decimalToPct, pctToDecimal } from './corrected_percent_convert'; + +export const adjustThresholdBasedOnFormat = ( + previous: CustomThresholdExpressionMetric[], + next: CustomThresholdExpressionMetric[], + threshold: number[] +) => { + const isPreviousPercent = Boolean(previous.length === 1 && previous[0].field?.endsWith('.pct')); + const isPercent = Boolean(next.length === 1 && next[0].field?.endsWith('.pct')); + return isPercent === isPreviousPercent + ? threshold + : isPercent + ? threshold.map((v: number) => pctToDecimal(v)) + : isPreviousPercent + ? threshold.map((v: number) => decimalToPct(v)) + : threshold; +}; diff --git a/x-pack/plugins/observability/public/components/custom_threshold/hooks/use_expression_chart_data.ts b/x-pack/plugins/observability/public/components/custom_threshold/hooks/use_expression_chart_data.ts index 1f135473c086..65bb84defa03 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/hooks/use_expression_chart_data.ts +++ b/x-pack/plugins/observability/public/components/custom_threshold/hooks/use_expression_chart_data.ts @@ -52,11 +52,10 @@ export const useExpressionChartData = ( equation: expression.equation, }, ], - aggregation: expression.aggType || 'custom', + aggregation: 'custom', }), // eslint-disable-next-line react-hooks/exhaustive-deps [ - expression.aggType, expression.equation, // eslint-disable-next-line react-hooks/exhaustive-deps JSON.stringify(expression.metrics), diff --git a/x-pack/plugins/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts b/x-pack/plugins/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts index f93bac2b0f10..4cae955ce980 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts +++ b/x-pack/plugins/observability/public/components/custom_threshold/mocks/custom_threshold_rule.ts @@ -6,7 +6,6 @@ */ import { v4 as uuidv4 } from 'uuid'; -import { CUSTOM_AGGREGATOR } from '../../../../common/custom_threshold_rule/constants'; import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types'; import { CustomThresholdAlert, CustomThresholdRule } from '../components/alert_details_app_section'; @@ -60,7 +59,6 @@ export const buildCustomThresholdRule = ( params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -73,7 +71,6 @@ export const buildCustomThresholdRule = ( timeUnit: 'm', }, { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -89,7 +86,6 @@ export const buildCustomThresholdRule = ( warningThreshold: [2.2], }, { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -155,7 +151,6 @@ export const buildCustomThresholdAlert = ( 'kibana.alert.rule.parameters': { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -169,7 +164,6 @@ export const buildCustomThresholdAlert = ( timeUnit: 'm', }, { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { diff --git a/x-pack/plugins/observability/public/components/custom_threshold/types.ts b/x-pack/plugins/observability/public/components/custom_threshold/types.ts index e726a8fd0132..dc0ad4eb7162 100644 --- a/x-pack/plugins/observability/public/components/custom_threshold/types.ts +++ b/x-pack/plugins/observability/public/components/custom_threshold/types.ts @@ -74,8 +74,6 @@ export interface InfraClientStartDeps { uiActions: UiActionsStart; unifiedSearch: UnifiedSearchPublicPluginStart; usageCollection: UsageCollectionStart; - // TODO:: check if needed => https://github.com/elastic/kibana/issues/159340 - // telemetry: ITelemetryClient; } export type RendererResult = React.ReactElement | null; diff --git a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.tsx b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.tsx index 485355a27872..76a1a0efef11 100644 --- a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.tsx +++ b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.tsx @@ -14,11 +14,12 @@ import { paths } from '../../../../common/locators/paths'; import { useKibana } from '../../../utils/kibana_react'; export interface Props { + viewMode?: 'compact' | 'default'; activeAlerts?: number; slo: SLOWithSummaryResponse; } -export function SloActiveAlertsBadge({ slo, activeAlerts }: Props) { +export function SloActiveAlertsBadge({ slo, activeAlerts, viewMode = 'default' }: Props) { const { application: { navigateToUrl }, http: { basePath }, @@ -50,10 +51,12 @@ export function SloActiveAlertsBadge({ slo, activeAlerts }: Props) { )} data-test-subj="o11ySloActiveAlertsBadge" > - {i18n.translate('xpack.observability.slo.slo.activeAlertsBadge.label', { - defaultMessage: '{count, plural, one {# alert} other {# alerts}}', - values: { count: activeAlerts }, - })} + {viewMode !== 'default' + ? activeAlerts + : i18n.translate('xpack.observability.slo.slo.activeAlertsBadge.label', { + defaultMessage: '{count, plural, one {# alert} other {# alerts}}', + values: { count: activeAlerts }, + })} ); diff --git a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_group_by_badge.tsx b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_group_by_badge.tsx index 455d6d9d24ed..f79b700ed9be 100644 --- a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_group_by_badge.tsx +++ b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_group_by_badge.tsx @@ -5,24 +5,25 @@ * 2.0. */ -import { EuiBadge, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { EuiBadge, EuiBadgeProps, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; -import { euiLightVars } from '@kbn/ui-theme'; import React from 'react'; +import { euiLightVars } from '@kbn/ui-theme'; export interface Props { + color?: EuiBadgeProps['color']; slo: SLOWithSummaryResponse; } -export function SloGroupByBadge({ slo }: Props) { +export function SloGroupByBadge({ slo, color }: Props) { if (!slo.groupBy || slo.groupBy === ALL_VALUE) { return null; } return ( - + { const location = await locator.getLocation({}); expect(location.app).toEqual('observability'); expect(location.path).toEqual( - "/slos?search=(kqlQuery:'',page:0,sort:(by:status,direction:desc))" + "/slos?search=(kqlQuery:'',page:0,sort:(by:status,direction:desc),viewMode:compact)" ); }); @@ -24,7 +24,7 @@ describe('SloListLocator', () => { }); expect(location.app).toEqual('observability'); expect(location.path).toEqual( - "/slos?search=(kqlQuery:'slo.name:%20%22Service%20Availability%22%20and%20slo.indicator.type%20:%20%22sli.kql.custom%22',page:0,sort:(by:status,direction:desc))" + "/slos?search=(kqlQuery:'slo.name:%20%22Service%20Availability%22%20and%20slo.indicator.type%20:%20%22sli.kql.custom%22',page:0,sort:(by:status,direction:desc),viewMode:compact)" ); }); }); diff --git a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.stories.tsx b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.stories.tsx index 267ebac0ce9b..67869e7f0e76 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.stories.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.stories.tsx @@ -11,7 +11,7 @@ import { ComponentStory } from '@storybook/react'; import { EuiFlexGroup } from '@elastic/eui'; import { buildForecastedSlo } from '../../../../data/slo/slo'; import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator'; -import { SloBadges as Component, Props } from './slo_badges'; +import { SloBadges as Component, SloBadgesProps } from './slo_badges'; export default { component: Component, @@ -19,7 +19,7 @@ export default { decorators: [KibanaReactStorybookDecorator], }; -const Template: ComponentStory = (props: Props) => ( +const Template: ComponentStory = (props: SloBadgesProps) => ( diff --git a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx index deccd010205a..9ff1e3c14a2b 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx @@ -17,8 +17,9 @@ import { SloTimeWindowBadge } from './slo_time_window_badge'; import { SloRulesBadge } from './slo_rules_badge'; import type { SloRule } from '../../../../hooks/slo/use_fetch_rules_for_slo'; import { SloGroupByBadge } from '../../../../components/slo/slo_status_badge/slo_group_by_badge'; +export type ViewMode = 'default' | 'compact'; -export interface Props { +export interface SloBadgesProps { activeAlerts?: number; isLoading: boolean; rules: Array> | undefined; @@ -26,33 +27,17 @@ export interface Props { onClickRuleBadge: () => void; } -export function SloBadges({ activeAlerts, isLoading, rules, slo, onClickRuleBadge }: Props) { +export function SloBadges({ + activeAlerts, + isLoading, + rules, + slo, + onClickRuleBadge, +}: SloBadgesProps) { return ( {isLoading ? ( - <> - - - - + ) : ( <> @@ -66,3 +51,31 @@ export function SloBadges({ activeAlerts, isLoading, rules, slo, onClickRuleBadg ); } + +export function LoadingBadges() { + return ( + <> + + + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_indicator_type_badge.tsx b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_indicator_type_badge.tsx index ad73af3d73bf..c85eb6776680 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_indicator_type_badge.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_indicator_type_badge.tsx @@ -6,21 +6,22 @@ */ import React from 'react'; -import { EuiBadge, EuiFlexItem, EuiToolTip } from '@elastic/eui'; +import { EuiBadge, EuiFlexItem, EuiToolTip, EuiBadgeProps } from '@elastic/eui'; import { SLOWithSummaryResponse } from '@kbn/slo-schema'; -import { euiLightVars } from '@kbn/ui-theme'; import { i18n } from '@kbn/i18n'; +import { euiLightVars } from '@kbn/ui-theme'; import { useKibana } from '../../../../utils/kibana_react'; import { convertSliApmParamsToApmAppDeeplinkUrl } from '../../../../utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url'; import { isApmIndicatorType } from '../../../../utils/slo/indicator'; import { toIndicatorTypeLabel } from '../../../../utils/slo/labels'; export interface Props { + color?: EuiBadgeProps['color']; slo: SLOWithSummaryResponse; } -export function SloIndicatorTypeBadge({ slo }: Props) { +export function SloIndicatorTypeBadge({ slo, color }: Props) { const { application: { navigateToUrl }, http: { basePath }, @@ -54,7 +55,7 @@ export function SloIndicatorTypeBadge({ slo }: Props) { return ( <> - + {toIndicatorTypeLabel(slo.indicator.type)} @@ -68,7 +69,7 @@ export function SloIndicatorTypeBadge({ slo }: Props) { })} > - + ); diff --git a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_time_window_badge.tsx b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_time_window_badge.tsx index d218eeda7f0e..b5d4ecd0224f 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_time_window_badge.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_time_window_badge.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { EuiBadge, EuiFlexItem } from '@elastic/eui'; +import { EuiBadge, EuiBadgeProps, EuiFlexItem } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { rollingTimeWindowTypeSchema, SLOWithSummaryResponse } from '@kbn/slo-schema'; import { euiLightVars } from '@kbn/ui-theme'; @@ -15,16 +15,17 @@ import { toCalendarAlignedMomentUnitOfTime } from '../../../../utils/slo/duratio import { toDurationLabel } from '../../../../utils/slo/labels'; export interface Props { + color?: EuiBadgeProps['color']; slo: SLOWithSummaryResponse; } -export function SloTimeWindowBadge({ slo }: Props) { +export function SloTimeWindowBadge({ slo, color }: Props) { const unit = slo.timeWindow.duration.slice(-1); if (rollingTimeWindowTypeSchema.is(slo.timeWindow.type)) { return ( @@ -45,7 +46,7 @@ export function SloTimeWindowBadge({ slo }: Props) { return ( - + {i18n.translate('xpack.observability.slo.slo.timeWindow.calendar', { defaultMessage: '{elapsed}/{total} days', values: { diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/cards_per_row.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/cards_per_row.tsx new file mode 100644 index 000000000000..04e787d7b353 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/cards_per_row.tsx @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { EuiFormRow, EuiSelect } from '@elastic/eui'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; + +export const SLO_CARD_VIEW_PER_ROW_SIZE = 'slo-card-view-per-row-size'; + +export function CardsPerRow({ + setCardsPerRow, +}: { + setCardsPerRow: (cardsPerRow?: string) => void; +}) { + const [value, setValue] = useLocalStorage(SLO_CARD_VIEW_PER_ROW_SIZE, '3'); + + useEffect(() => { + setCardsPerRow(value); + }, [setCardsPerRow, value]); + + const options = [ + { value: '3', text: '3' }, + { value: '4', text: '4' }, + ]; + + return ( + + } + > + setValue(e.target.value)} + /> + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item.tsx new file mode 100644 index 000000000000..07ad3caf1fd0 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item.tsx @@ -0,0 +1,181 @@ +/* + * 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, { useState } from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + Chart, + isMetricElementEvent, + Metric, + Settings, + DARK_THEME, + MetricTrendShape, +} from '@elastic/charts'; +import { EuiIcon, EuiPanel, useEuiBackgroundColor } from '@elastic/eui'; +import { SLOWithSummaryResponse, HistoricalSummaryResponse, ALL_VALUE } from '@kbn/slo-schema'; +import { Rule } from '@kbn/triggers-actions-ui-plugin/public'; +import { i18n } from '@kbn/i18n'; +import { useSloListActions } from '../../hooks/use_slo_list_actions'; +import { BurnRateRuleFlyout } from '../common/burn_rate_rule_flyout'; +import { formatHistoricalData } from '../../../../utils/slo/chart_data_formatter'; +import { useKibana } from '../../../../utils/kibana_react'; +import { useSloFormattedSummary } from '../../hooks/use_slo_summary'; +import { SloCardItemActions } from './slo_card_item_actions'; +import { SloRule } from '../../../../hooks/slo/use_fetch_rules_for_slo'; +import { SloDeleteConfirmationModal } from '../../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal'; +import { SloCardItemBadges } from './slo_card_item_badges'; + +export interface Props { + slo: SLOWithSummaryResponse; + rules: Array> | undefined; + historicalSummary?: HistoricalSummaryResponse[]; + historicalSummaryLoading: boolean; + activeAlerts?: number; + loading: boolean; + error: boolean; + cardsPerRow: number; +} + +const useCardColor = (status?: SLOWithSummaryResponse['summary']['status']) => { + const colors = { + DEGRADING: useEuiBackgroundColor('warning'), + VIOLATED: useEuiBackgroundColor('danger'), + HEALTHY: useEuiBackgroundColor('success'), + NO_DATA: useEuiBackgroundColor('subdued'), + }; + + return colors[status ?? 'NO_DATA']; +}; + +const getSubTitle = (slo: SLOWithSummaryResponse, cardsPerRow: number) => { + const subTitle = + slo.groupBy && slo.groupBy !== ALL_VALUE ? `${slo.groupBy}: ${slo.instanceId}` : ''; + if (cardsPerRow === 4) { + return subTitle.substring(0, 30) + (subTitle.length > 30 ? '..' : ''); + } + return subTitle.substring(0, 40) + (subTitle.length > 40 ? '..' : ''); +}; + +export function SloCardItem({ slo, rules, activeAlerts, historicalSummary, cardsPerRow }: Props) { + const { + application: { navigateToUrl }, + } = useKibana().services; + + const [isMouseOver, setIsMouseOver] = useState(false); + const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false); + const [isAddRuleFlyoutOpen, setIsAddRuleFlyoutOpen] = useState(false); + const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false); + + const { sliValue, sloTarget, sloDetailsUrl } = useSloFormattedSummary(slo); + + const cardColor = useCardColor(slo.summary.status); + + const subTitle = getSubTitle(slo, cardsPerRow); + + const historicalSliData = formatHistoricalData(historicalSummary, 'sli_value'); + + const { handleCreateRule, handleDeleteCancel, handleDeleteConfirm } = useSloListActions({ + slo, + setDeleteConfirmationModalOpen, + setIsActionsPopoverOpen, + setIsAddRuleFlyoutOpen, + }); + + return ( + <> + { + if (!isMouseOver) { + setIsMouseOver(true); + } + }} + onMouseLeave={() => { + if (isMouseOver) { + setIsMouseOver(false); + } + }} + paddingSize="none" + style={{ + height: '182px', + overflow: 'hidden', + position: 'relative', + }} + title={slo.summary.status} + > + + { + if (isMetricElementEvent(d)) { + navigateToUrl(sloDetailsUrl); + } + }} + locale={i18n.getLocale()} + /> + ({ + x: d.key as number, + y: d.value as number, + })), + extra: ( + + ), + icon: () => , + color: cardColor, + }, + ], + ]} + /> + + + {(isMouseOver || isActionsPopoverOpen) && ( + + )} + + + + + {isDeleteConfirmationModalOpen ? ( + + ) : null} + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_actions.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_actions.tsx new file mode 100644 index 000000000000..51d1887d433f --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_actions.tsx @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React from 'react'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import styled from 'styled-components'; +import { useEuiShadow } from '@elastic/eui'; +import { SloItemActions } from '../slo_item_actions'; + +type PopoverPosition = 'relative' | 'default'; + +interface ActionContainerProps { + boxShadow: string; + position: PopoverPosition; +} + +const Container = styled.div` + ${({ position }) => + position === 'relative' + ? // custom styles used to overlay the popover button on `MetricItem` + ` + display: inline-block; + position: relative; + bottom: 42px; + left: 12px; + z-index: 1; +` + : // otherwise, no custom position needed + ''} + + border-radius: ${({ theme }) => theme.eui.euiBorderRadius}; + ${({ boxShadow, position }) => (position === 'relative' ? boxShadow : '')} +`; + +interface Props { + slo: SLOWithSummaryResponse; + isActionsPopoverOpen: boolean; + setIsActionsPopoverOpen: (value: boolean) => void; + setDeleteConfirmationModalOpen: (value: boolean) => void; + setIsAddRuleFlyoutOpen: (value: boolean) => void; +} + +export function SloCardItemActions(props: Props) { + const euiShadow = useEuiShadow('l'); + + return ( + + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_badges.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_badges.tsx new file mode 100644 index 000000000000..06bc6cf19e0c --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/slo_card_item_badges.tsx @@ -0,0 +1,60 @@ +/* + * 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 { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import React from 'react'; +import { Rule } from '@kbn/triggers-actions-ui-plugin/public'; +import styled from 'styled-components'; +import { EuiFlexGroup } from '@elastic/eui'; +import { LoadingBadges } from '../badges/slo_badges'; +import { SloIndicatorTypeBadge } from '../badges/slo_indicator_type_badge'; +import { SloTimeWindowBadge } from '../badges/slo_time_window_badge'; +import { SloActiveAlertsBadge } from '../../../../components/slo/slo_status_badge/slo_active_alerts_badge'; +import { SloRulesBadge } from '../badges/slo_rules_badge'; +import { SloRule } from '../../../../hooks/slo/use_fetch_rules_for_slo'; + +interface Props { + hasGroupBy: boolean; + activeAlerts?: number; + slo: SLOWithSummaryResponse; + rules: Array> | undefined; + handleCreateRule: () => void; +} + +const Container = styled.div<{ hasGroupBy: boolean }>` + position: absolute; + display: inline-block; + top: ${({ hasGroupBy }) => (hasGroupBy ? '55px' : '35px')}; + left: 7px; + z-index: 1; + border-radius: ${({ theme }) => theme.eui.euiBorderRadius}; +`; + +export function SloCardItemBadges({ + slo, + activeAlerts, + rules, + handleCreateRule, + hasGroupBy, +}: Props) { + return ( + + + {!slo.summary ? ( + + ) : ( + <> + + + + + + )} + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx b/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx new file mode 100644 index 000000000000..3768bdbb7dac --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/card_view/slos_card_view.tsx @@ -0,0 +1,86 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFlexGrid, EuiFlexItem, EuiPanel, EuiSkeletonText } from '@elastic/eui'; +import { SLOWithSummaryResponse, ALL_VALUE } from '@kbn/slo-schema'; +import { EuiFlexGridProps } from '@elastic/eui/src/components/flex/flex_grid'; +import { ActiveAlerts } from '../../../../hooks/slo/use_fetch_active_alerts'; +import type { UseFetchRulesForSloResponse } from '../../../../hooks/slo/use_fetch_rules_for_slo'; +import { useFetchHistoricalSummary } from '../../../../hooks/slo/use_fetch_historical_summary'; +import { SloCardItem } from './slo_card_item'; + +export interface Props { + sloList: SLOWithSummaryResponse[]; + loading: boolean; + error: boolean; + cardsPerRow?: string; + activeAlertsBySlo: ActiveAlerts; + rulesBySlo?: UseFetchRulesForSloResponse['data']; +} + +export function SloListCardView({ + sloList, + loading, + error, + cardsPerRow, + rulesBySlo, + activeAlertsBySlo, +}: Props) { + const { isLoading: historicalSummaryLoading, data: historicalSummaries = [] } = + useFetchHistoricalSummary({ + list: sloList.map((slo) => ({ sloId: slo.id, instanceId: slo.instanceId ?? ALL_VALUE })), + }); + + if (loading && sloList.length === 0) { + return ; + } + + return ( + + {sloList.map((slo) => ( + + + historicalSummary.sloId === slo.id && + historicalSummary.instanceId === (slo.instanceId ?? ALL_VALUE) + )?.data + } + historicalSummaryLoading={historicalSummaryLoading} + cardsPerRow={Number(cardsPerRow)} + /> + + ))} + + ); +} + +function LoadingSloGrid({ gridSize }: { gridSize: number }) { + const ROWS = 4; + const COLUMNS = gridSize; + const loaders = Array(ROWS * COLUMNS).fill(null); + return ( + <> + + {loaders.map((_, i) => ( + + + + {' '} + + ))} + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx b/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx new file mode 100644 index 000000000000..a02730231ae5 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/common/burn_rate_rule_flyout.tsx @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { useQueryClient } from '@tanstack/react-query'; +import { useGetFilteredRuleTypes } from '../../../../hooks/use_get_filtered_rule_types'; +import { sloKeys } from '../../../../hooks/slo/query_key_factory'; +import { useKibana } from '../../../../utils/kibana_react'; +import { SLO_BURN_RATE_RULE_TYPE_ID } from '../../../../../common/constants'; +import { sloFeatureId } from '../../../../../common'; + +export function BurnRateRuleFlyout({ + slo, + isAddRuleFlyoutOpen, + setIsAddRuleFlyoutOpen, +}: { + slo: SLOWithSummaryResponse; + isAddRuleFlyoutOpen: boolean; + setIsAddRuleFlyoutOpen: (value: boolean) => void; +}) { + const { + triggersActionsUi: { getAddRuleFlyout: AddRuleFlyout }, + } = useKibana().services; + + const filteredRuleTypes = useGetFilteredRuleTypes(); + + const queryClient = useQueryClient(); + + const handleSavedRule = async () => { + queryClient.invalidateQueries({ queryKey: sloKeys.rules(), exact: false }); + }; + + return isAddRuleFlyoutOpen ? ( + { + setIsAddRuleFlyoutOpen(false); + }} + useRuleProducer + /> + ) : null; +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx new file mode 100644 index 000000000000..4fb03968d40a --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_item_actions.tsx @@ -0,0 +1,217 @@ +/* + * 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 { + EuiButtonIcon, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiPopover, + EuiButtonIconProps, + useEuiShadow, + EuiPanel, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import styled from 'styled-components'; +import { useCapabilities } from '../../../hooks/slo/use_capabilities'; +import { useCloneSlo } from '../../../hooks/slo/use_clone_slo'; +import { useKibana } from '../../../utils/kibana_react'; +import { paths } from '../../../../common/locators/paths'; +import { RulesParams } from '../../../locators/rules'; +import { rulesLocatorID } from '../../../../common'; +import { + transformCreateSLOFormToCreateSLOInput, + transformSloResponseToCreateSloForm, +} from '../../slo_edit/helpers/process_slo_form_values'; + +interface Props { + slo: SLOWithSummaryResponse; + isActionsPopoverOpen: boolean; + setIsActionsPopoverOpen: (value: boolean) => void; + setDeleteConfirmationModalOpen: (value: boolean) => void; + setIsAddRuleFlyoutOpen: (value: boolean) => void; + btnProps?: Partial; +} +const CustomShadowPanel = styled(EuiPanel)<{ shadow: string }>` + ${(props) => props.shadow} +`; + +function IconPanel({ children, hasPanel }: { children: JSX.Element; hasPanel: boolean }) { + const shadow = useEuiShadow('s'); + if (!hasPanel) return children; + return ( + + {children} + + ); +} + +export function SloItemActions({ + slo, + isActionsPopoverOpen, + setIsActionsPopoverOpen, + setIsAddRuleFlyoutOpen, + setDeleteConfirmationModalOpen, + btnProps, +}: Props) { + const { + application: { navigateToUrl }, + http: { basePath }, + share: { + url: { locators }, + }, + } = useKibana().services; + const { hasWriteCapabilities } = useCapabilities(); + const { mutate: cloneSlo } = useCloneSlo(); + + const sloDetailsUrl = basePath.prepend( + paths.observability.sloDetails( + slo.id, + slo.groupBy !== ALL_VALUE && slo.instanceId ? slo.instanceId : undefined + ) + ); + + const handleClickActions = () => { + setIsActionsPopoverOpen(!isActionsPopoverOpen); + }; + + const handleViewDetails = () => { + navigateToUrl(sloDetailsUrl); + }; + + const handleEdit = () => { + navigateToUrl(basePath.prepend(paths.observability.sloEdit(slo.id))); + }; + + const handleNavigateToRules = async () => { + const locator = locators.get(rulesLocatorID); + locator?.navigate({ params: { sloId: slo.id } }, { replace: false }); + }; + + const handleClone = () => { + const newSlo = transformCreateSLOFormToCreateSLOInput( + transformSloResponseToCreateSloForm({ ...slo, name: `[Copy] ${slo.name}` })! + ); + + cloneSlo({ slo: newSlo, originalSloId: slo.id }); + setIsActionsPopoverOpen(false); + }; + + const handleDelete = () => { + setDeleteConfirmationModalOpen(true); + setIsActionsPopoverOpen(false); + }; + + const handleCreateRule = () => { + setIsActionsPopoverOpen(false); + setIsAddRuleFlyoutOpen(true); + }; + + const btn = ( + + ); + + return ( + {btn} : btn} + panelPaddingSize="m" + closePopover={handleClickActions} + isOpen={isActionsPopoverOpen} + > + + {i18n.translate('xpack.observability.slo.item.actions.details', { + defaultMessage: 'Details', + })} + , + + {i18n.translate('xpack.observability.slo.item.actions.edit', { + defaultMessage: 'Edit', + })} + , + + {i18n.translate('xpack.observability.slo.item.actions.createRule', { + defaultMessage: 'Create new alert rule', + })} + , + + {i18n.translate('xpack.observability.slo.item.actions.manageRules', { + defaultMessage: 'Manage rules', + })} + , + + {i18n.translate('xpack.observability.slo.item.actions.clone', { + defaultMessage: 'Clone', + })} + , + + {i18n.translate('xpack.observability.slo.item.actions.delete', { + defaultMessage: 'Delete', + })} + , + ]} + /> + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx index 380d0100db1a..ee1fff8e17c1 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list.tsx @@ -8,9 +8,12 @@ import { EuiFlexGroup, EuiFlexItem, EuiPagination } from '@elastic/eui'; import { useIsMutating } from '@tanstack/react-query'; import React, { useState } from 'react'; +import useLocalStorage from 'react-use/lib/useLocalStorage'; +import { SlosView } from './slos_view'; +import { SLO_CARD_VIEW_PER_ROW_SIZE } from './card_view/cards_per_row'; +import { SLOViewType, ToggleSLOView } from './toggle_slo_view'; import { useFetchSloList } from '../../../hooks/slo/use_fetch_slo_list'; import { useUrlSearchState } from '../hooks/use_url_search_state'; -import { SloListItems } from './slo_list_items'; import { SloListSearchBar, SortField } from './slo_list_search_bar'; export interface Props { @@ -24,6 +27,8 @@ export function SloList({ autoRefresh }: Props) { const [sort, setSort] = useState(state.sort.by); const [direction] = useState<'asc' | 'desc'>(state.sort.direction); + const [sloView, setSLOView] = useState('cardView'); + const { isLoading, isRefetching, @@ -43,6 +48,7 @@ export function SloList({ autoRefresh }: Props) { const isCloningSlo = Boolean(useIsMutating(['cloningSlo'])); const isUpdatingSlo = Boolean(useIsMutating(['updatingSlo'])); const isDeletingSlo = Boolean(useIsMutating(['deleteSlo'])); + const [cardsPerRow, setCardsPerRow] = useLocalStorage(SLO_CARD_VIEW_PER_ROW_SIZE, '4'); const handlePageClick = (pageNumber: number) => { setPage(pageNumber); @@ -71,9 +77,16 @@ export function SloList({ autoRefresh }: Props) { initialState={state} /> - - + + + {total > 0 ? ( diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx index ae843977a0ee..90757be5dc7a 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_list_item.tsx @@ -5,37 +5,16 @@ * 2.0. */ -import { - EuiButtonIcon, - EuiContextMenuItem, - EuiContextMenuPanel, - EuiFlexGroup, - EuiFlexItem, - EuiPanel, - EuiPopover, - EuiText, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { ALL_VALUE, HistoricalSummaryResponse, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; +import { HistoricalSummaryResponse, SLOWithSummaryResponse } from '@kbn/slo-schema'; import type { Rule } from '@kbn/triggers-actions-ui-plugin/public'; -import { useQueryClient } from '@tanstack/react-query'; import React, { useState } from 'react'; +import { useSloFormattedSummary } from '../hooks/use_slo_summary'; +import { BurnRateRuleFlyout } from './common/burn_rate_rule_flyout'; +import { useSloListActions } from '../hooks/use_slo_list_actions'; +import { SloItemActions } from './slo_item_actions'; import { SloDeleteConfirmationModal } from '../../../components/slo/delete_confirmation_modal/slo_delete_confirmation_modal'; -import { rulesLocatorID, sloFeatureId } from '../../../../common'; -import { SLO_BURN_RATE_RULE_TYPE_ID } from '../../../../common/constants'; -import { paths } from '../../../../common/locators/paths'; -import { sloKeys } from '../../../hooks/slo/query_key_factory'; -import { useCapabilities } from '../../../hooks/slo/use_capabilities'; -import { useCloneSlo } from '../../../hooks/slo/use_clone_slo'; -import { useDeleteSlo } from '../../../hooks/slo/use_delete_slo'; import type { SloRule } from '../../../hooks/slo/use_fetch_rules_for_slo'; -import { useGetFilteredRuleTypes } from '../../../hooks/use_get_filtered_rule_types'; -import type { RulesParams } from '../../../locators/rules'; -import { useKibana } from '../../../utils/kibana_react'; -import { - transformCreateSLOFormToCreateSLOInput, - transformSloResponseToCreateSloForm, -} from '../../slo_edit/helpers/process_slo_form_values'; import { SloBadges } from './badges/slo_badges'; import { SloSummary } from './slo_summary'; @@ -54,80 +33,18 @@ export function SloListItem({ historicalSummaryLoading, activeAlerts, }: SloListItemProps) { - const { - application: { navigateToUrl }, - http: { basePath }, - share: { - url: { locators }, - }, - triggersActionsUi: { getAddRuleFlyout: AddRuleFlyout }, - } = useKibana().services; - const { hasWriteCapabilities } = useCapabilities(); - const queryClient = useQueryClient(); - - const filteredRuleTypes = useGetFilteredRuleTypes(); - - const { mutate: cloneSlo } = useCloneSlo(); - const { mutate: deleteSlo } = useDeleteSlo(); - const [isActionsPopoverOpen, setIsActionsPopoverOpen] = useState(false); const [isAddRuleFlyoutOpen, setIsAddRuleFlyoutOpen] = useState(false); const [isDeleteConfirmationModalOpen, setDeleteConfirmationModalOpen] = useState(false); - const handleClickActions = () => { - setIsActionsPopoverOpen(!isActionsPopoverOpen); - }; - - const sloDetailsUrl = basePath.prepend( - paths.observability.sloDetails( - slo.id, - slo.groupBy !== ALL_VALUE && slo.instanceId ? slo.instanceId : undefined - ) - ); - const handleViewDetails = () => { - navigateToUrl(sloDetailsUrl); - }; - - const handleEdit = () => { - navigateToUrl(basePath.prepend(paths.observability.sloEdit(slo.id))); - }; - - const handleCreateRule = () => { - setIsActionsPopoverOpen(false); - setIsAddRuleFlyoutOpen(true); - }; - - const handleSavedRule = async () => { - queryClient.invalidateQueries({ queryKey: sloKeys.rules(), exact: false }); - }; + const { sloDetailsUrl } = useSloFormattedSummary(slo); - const handleNavigateToRules = async () => { - const locator = locators.get(rulesLocatorID); - locator?.navigate({ params: { sloId: slo.id } }, { replace: false }); - }; - - const handleClone = () => { - const newSlo = transformCreateSLOFormToCreateSLOInput( - transformSloResponseToCreateSloForm({ ...slo, name: `[Copy] ${slo.name}` })! - ); - - cloneSlo({ slo: newSlo, originalSloId: slo.id }); - setIsActionsPopoverOpen(false); - }; - - const handleDelete = () => { - setDeleteConfirmationModalOpen(true); - setIsActionsPopoverOpen(false); - }; - - const handleDeleteConfirm = () => { - setDeleteConfirmationModalOpen(false); - deleteSlo({ id: slo.id, name: slo.name }); - }; - - const handleDeleteCancel = () => { - setDeleteConfirmationModalOpen(false); - }; + const { handleCreateRule, handleDeleteCancel, handleDeleteConfirm } = useSloListActions({ + slo, + setDeleteConfirmationModalOpen, + setIsActionsPopoverOpen, + setIsAddRuleFlyoutOpen, + }); return ( @@ -172,113 +89,21 @@ export function SloListItem({ {/* ACTIONS */} - - } - panelPaddingSize="m" - closePopover={handleClickActions} - isOpen={isActionsPopoverOpen} - > - - {i18n.translate('xpack.observability.slo.item.actions.details', { - defaultMessage: 'Details', - })} - , - - {i18n.translate('xpack.observability.slo.item.actions.edit', { - defaultMessage: 'Edit', - })} - , - - {i18n.translate('xpack.observability.slo.item.actions.createRule', { - defaultMessage: 'Create new alert rule', - })} - , - - {i18n.translate('xpack.observability.slo.item.actions.manageRules', { - defaultMessage: 'Manage rules', - })} - , - - {i18n.translate('xpack.observability.slo.item.actions.clone', { - defaultMessage: 'Clone', - })} - , - - {i18n.translate('xpack.observability.slo.item.actions.delete', { - defaultMessage: 'Delete', - })} - , - ]} - /> - + - {isAddRuleFlyoutOpen ? ( - { - setIsAddRuleFlyoutOpen(false); - }} - useRuleProducer - /> - ) : null} + {isDeleteConfirmationModalOpen ? ( = (props: Props) => [slo.id, slo.instanceId ?? ALL_VALUE] as [string, string] - ); - - const { data: activeAlertsBySlo } = useFetchActiveAlerts({ sloIdsAndInstanceIds }); - const { data: rulesBySlo } = useFetchRulesForSlo({ - sloIds: sloIdsAndInstanceIds.map((item) => item[0]), - }); +export function SloListItems({ sloList, activeAlertsBySlo, rulesBySlo }: Props) { const { isLoading: historicalSummaryLoading, data: historicalSummaries = [] } = useFetchHistoricalSummary({ list: sloList.map((slo) => ({ sloId: slo.id, instanceId: slo.instanceId ?? ALL_VALUE })), }); - if (!loading && !error && sloList.length === 0) { - return ; - } - if (!loading && error) { - return ; - } - return ( {sloList.map((slo) => ( diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx index 401118e3c8df..77d23d6301ae 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx @@ -6,13 +6,11 @@ */ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiStat } from '@elastic/eui'; -import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; import { HistoricalSummaryResponse, SLOWithSummaryResponse } from '@kbn/slo-schema'; -import { useKibana } from '../../../utils/kibana_react'; +import { useSloFormattedSummary } from '../hooks/use_slo_summary'; import { formatHistoricalData } from '../../../utils/slo/chart_data_formatter'; -import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n'; import { SloSparkline } from './slo_sparkline'; export interface Props { @@ -22,18 +20,12 @@ export interface Props { } export function SloSummary({ slo, historicalSummary = [], historicalSummaryLoading }: Props) { - const { uiSettings } = useKibana().services; - const percentFormat = uiSettings.get('format:percent:defaultPattern'); + const { sliValue, sloTarget, errorBudgetRemaining } = useSloFormattedSummary(slo); const isSloFailed = slo.summary.status === 'VIOLATED' || slo.summary.status === 'DEGRADING'; const titleColor = isSloFailed ? 'danger' : ''; const errorBudgetBurnDownData = formatHistoricalData(historicalSummary, 'error_budget_remaining'); const historicalSliData = formatHistoricalData(historicalSummary, 'sli_value'); - const errorBudgetRemaining = - slo.summary.errorBudget.remaining <= 0 - ? Math.trunc(slo.summary.errorBudget.remaining * 100) / 100 - : slo.summary.errorBudget.remaining; - return ( @@ -48,13 +40,9 @@ export function SloSummary({ slo, historicalSummary = [], historicalSummaryLoadi [slo.id, slo.instanceId ?? ALL_VALUE] as [string, string] + ); + + const { data: activeAlertsBySlo } = useFetchActiveAlerts({ sloIdsAndInstanceIds }); + const { data: rulesBySlo } = useFetchRulesForSlo({ + sloIds: sloIdsAndInstanceIds.map((item) => item[0]), + }); + + if (!loading && !error && sloList.length === 0) { + return ; + } + if (!loading && error) { + return ; + } + + return sloView === 'cardView' ? ( + + + + ) : ( + + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/components/toggle_slo_view.tsx b/x-pack/plugins/observability/public/pages/slos/components/toggle_slo_view.tsx new file mode 100644 index 000000000000..43b5d849b2e0 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/components/toggle_slo_view.tsx @@ -0,0 +1,97 @@ +/* + * 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 { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; +import { + EuiButtonGroup, + EuiButtonIcon, + EuiFlexGroup, + EuiFlexItem, + EuiPopover, + EuiPopoverTitle, +} from '@elastic/eui'; +import { CardsPerRow } from './card_view/cards_per_row'; + +export type SLOViewType = 'cardView' | 'listView'; + +interface Props { + setCardsPerRow: (gridSize?: string) => void; + setSLOView: (view: SLOViewType) => void; + sloView: SLOViewType; +} +const toggleButtonsIcons = [ + { + id: `cardView`, + label: 'Card View', + iconType: 'visGauge', + 'data-test-subj': 'sloCardViewButton', + }, + { + id: `listView`, + label: 'List View', + iconType: 'list', + 'data-test-subj': 'sloListViewButton', + }, +]; + +export function ToggleSLOView({ sloView, setSLOView, setCardsPerRow }: Props) { + return ( + + + setSLOView(id as SLOViewType)} + isIconOnly + /> + + {sloView === 'cardView' && ( + + + + )} + + ); +} + +function ViewSettings({ setCardsPerRow }: { setCardsPerRow: (cardsPerRow?: string) => void }) { + const [isPopoverOpen, setIsPopoverOpen] = React.useState(false); + + return ( + setIsPopoverOpen(!isPopoverOpen)} + /> + } + isOpen={isPopoverOpen} + closePopover={() => setIsPopoverOpen(false)} + anchorPosition="downCenter" + > + + + +
    + +
    +
    + ); +} diff --git a/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_list_actions.ts b/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_list_actions.ts new file mode 100644 index 000000000000..169e1e54c522 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_list_actions.ts @@ -0,0 +1,42 @@ +/* + * 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 { SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { useDeleteSlo } from '../../../hooks/slo/use_delete_slo'; + +export function useSloListActions({ + slo, + setIsAddRuleFlyoutOpen, + setIsActionsPopoverOpen, + setDeleteConfirmationModalOpen, +}: { + slo: SLOWithSummaryResponse; + setIsActionsPopoverOpen: (val: boolean) => void; + setIsAddRuleFlyoutOpen: (val: boolean) => void; + setDeleteConfirmationModalOpen: (val: boolean) => void; +}) { + const { mutate: deleteSlo } = useDeleteSlo(); + + const handleDeleteConfirm = () => { + setDeleteConfirmationModalOpen(false); + deleteSlo({ id: slo.id, name: slo.name }); + }; + + const handleDeleteCancel = () => { + setDeleteConfirmationModalOpen(false); + }; + const handleCreateRule = () => { + setIsActionsPopoverOpen(false); + setIsAddRuleFlyoutOpen(true); + }; + + return { + handleDeleteConfirm, + handleDeleteCancel, + handleCreateRule, + }; +} diff --git a/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_summary.ts b/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_summary.ts new file mode 100644 index 000000000000..547bd41b4f5d --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slos/hooks/use_slo_summary.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import numeral from '@elastic/numeral'; +import { ALL_VALUE, SLOWithSummaryResponse } from '@kbn/slo-schema'; +import { paths } from '../../../../common/locators/paths'; +import { useKibana } from '../../../utils/kibana_react'; +import { NOT_AVAILABLE_LABEL } from '../../../../common/i18n'; + +export const useSloFormattedSummary = (slo: SLOWithSummaryResponse) => { + const { + http: { basePath }, + } = useKibana().services; + const { uiSettings } = useKibana().services; + const percentFormat = uiSettings.get('format:percent:defaultPattern'); + + const sliValue = + slo.summary.status === 'NO_DATA' + ? NOT_AVAILABLE_LABEL + : numeral(slo.summary.sliValue).format(percentFormat); + + const sloTarget = numeral(slo.objective.target).format(percentFormat); + const errorBudgetRemaining = + slo.summary.errorBudget.remaining <= 0 + ? Math.trunc(slo.summary.errorBudget.remaining * 100) / 100 + : slo.summary.errorBudget.remaining; + + const errorBudgetRemainingTitle = + slo.summary.status === 'NO_DATA' + ? NOT_AVAILABLE_LABEL + : numeral(errorBudgetRemaining).format(percentFormat); + + const sloDetailsUrl = basePath.prepend( + paths.observability.sloDetails( + slo.id, + slo.groupBy !== ALL_VALUE && slo.instanceId ? slo.instanceId : undefined + ) + ); + + return { + sloDetailsUrl, + sliValue, + sloTarget, + errorBudgetRemaining: errorBudgetRemainingTitle, + }; +}; diff --git a/x-pack/plugins/observability/public/pages/slos/hooks/use_url_search_state.ts b/x-pack/plugins/observability/public/pages/slos/hooks/use_url_search_state.ts index 7a0c03215fb9..aaa87cb921ae 100644 --- a/x-pack/plugins/observability/public/pages/slos/hooks/use_url_search_state.ts +++ b/x-pack/plugins/observability/public/pages/slos/hooks/use_url_search_state.ts @@ -8,6 +8,7 @@ import { useHistory } from 'react-router-dom'; import { createKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public'; import deepmerge from 'deepmerge'; +import { ViewMode } from '../components/badges/slo_badges'; import type { SortField } from '../components/slo_list_search_bar'; export const SLO_LIST_SEARCH_URL_STORAGE_KEY = 'search'; @@ -19,12 +20,14 @@ export interface SearchState { by: SortField; direction: 'asc' | 'desc'; }; + viewMode: ViewMode; } export const DEFAULT_STATE = { kqlQuery: '', page: 0, sort: { by: 'status' as const, direction: 'desc' as const }, + viewMode: 'compact' as const, }; export function useUrlSearchState(): { diff --git a/x-pack/plugins/observability/public/pages/slos/slos.test.tsx b/x-pack/plugins/observability/public/pages/slos/slos.test.tsx index 3e19b7a466be..6c63d270ef8e 100644 --- a/x-pack/plugins/observability/public/pages/slos/slos.test.tsx +++ b/x-pack/plugins/observability/public/pages/slos/slos.test.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import { act, screen, waitFor } from '@testing-library/react'; +import { act, fireEvent, screen, waitFor } from '@testing-library/react'; import React from 'react'; import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; @@ -211,6 +211,9 @@ describe('SLOs Page', () => { await act(async () => { render(); }); + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + + fireEvent.click(screen.getByTestId('sloListViewButton')); expect(screen.queryByTestId('slosPage')).toBeTruthy(); expect(screen.queryByTestId('sloList')).toBeTruthy(); @@ -229,6 +232,8 @@ describe('SLOs Page', () => { await act(async () => { render(); }); + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + fireEvent.click(screen.getByTestId('sloListViewButton')); screen.getAllByLabelText('Actions').at(0)?.click(); @@ -256,7 +261,8 @@ describe('SLOs Page', () => { await act(async () => { render(); }); - + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + fireEvent.click(screen.getByTestId('sloListViewButton')); screen.getAllByLabelText('Actions').at(0)?.click(); await waitForEuiPopoverOpen(); @@ -281,7 +287,8 @@ describe('SLOs Page', () => { await act(async () => { render(); }); - + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + fireEvent.click(screen.getByTestId('sloListViewButton')); screen.getAllByLabelText('Actions').at(0)?.click(); await waitForEuiPopoverOpen(); @@ -307,6 +314,8 @@ describe('SLOs Page', () => { render(); }); + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + fireEvent.click(screen.getByTestId('sloListViewButton')); screen.getAllByLabelText('Actions').at(0)?.click(); await waitForEuiPopoverOpen(); @@ -337,6 +346,8 @@ describe('SLOs Page', () => { render(); }); + expect(await screen.findByTestId('sloListViewButton')).toBeTruthy(); + fireEvent.click(screen.getByTestId('sloListViewButton')); screen.getAllByLabelText('Actions').at(0)?.click(); await waitForEuiPopoverOpen(); diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts index e5301b8ac8da..c2340fbc046f 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/custom_threshold_executor.test.ts @@ -21,7 +21,6 @@ import { CustomThresholdAlertContext } from './types'; import { Evaluation } from './lib/evaluate_rule'; import type { LogMeta, Logger } from '@kbn/logging'; import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common'; -import { CUSTOM_AGGREGATOR } from '../../../../common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -1883,7 +1882,6 @@ declare global { } const customThresholdNonCountCriterion: CustomMetricExpressionParams = { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { @@ -1898,7 +1896,6 @@ const customThresholdNonCountCriterion: CustomMetricExpressionParams = { }; const customThresholdCountCriterion: CustomMetricExpressionParams = { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, metrics: [ { diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.test.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.test.ts index 53a89303fa17..01d94dd5f7d6 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.test.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/lib/metric_query.test.ts @@ -6,7 +6,6 @@ */ import moment from 'moment'; -import { CUSTOM_AGGREGATOR } from '../../../../../common/custom_threshold_rule/constants'; import { Comparator, Aggregators, @@ -23,7 +22,6 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => { field: 'system.is.a.good.puppy.dog', }, ], - aggType: CUSTOM_AGGREGATOR, timeUnit: 'm', timeSize: 1, threshold: [1], diff --git a/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts b/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts index 2166c21db860..db4402dca7e8 100644 --- a/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts +++ b/x-pack/plugins/observability/server/lib/rules/custom_threshold/register_custom_threshold_rule_type.ts @@ -43,7 +43,6 @@ import { oneOfLiterals, validateKQLStringFilter } from './utils'; import { createCustomThresholdExecutor } from './custom_threshold_executor'; import { FIRED_ACTION, NO_DATA_ACTION } from './constants'; import { ObservabilityConfig } from '../../..'; -import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/custom_threshold_rule/constants'; export const MetricsRulesTypeAlertDefinition: IRuleTypeAlerts = { context: THRESHOLD_RULE_REGISTRATION_CONTEXT, @@ -79,27 +78,9 @@ export function thresholdRuleType( timeSize: schema.number(), }; - const nonCountCriterion = schema.object({ - ...baseCriterion, - metric: schema.string(), - aggType: oneOfLiterals(METRIC_EXPLORER_AGGREGATIONS), - metrics: schema.never(), - equation: schema.never(), - label: schema.never(), - }); - - const countCriterion = schema.object({ - ...baseCriterion, - aggType: schema.literal('count'), - metric: schema.never(), - metrics: schema.never(), - equation: schema.never(), - label: schema.never(), - }); - const customCriterion = schema.object({ ...baseCriterion, - aggType: schema.literal('custom'), + aggType: schema.maybe(schema.literal('custom')), metric: schema.never(), metrics: schema.arrayOf( schema.oneOf([ @@ -133,9 +114,7 @@ export function thresholdRuleType( validate: { params: schema.object( { - criteria: schema.arrayOf( - schema.oneOf([countCriterion, nonCountCriterion, customCriterion]) - ), + criteria: schema.arrayOf(customCriterion), groupBy: schema.maybe(schema.oneOf([schema.string(), schema.arrayOf(schema.string())])), alertOnNoData: schema.maybe(schema.boolean()), alertOnGroupDisappear: schema.maybe(schema.boolean()), 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 8c6463ca9318..8f9c477c5d4e 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 @@ -280,7 +280,15 @@ function ChatContent({ ); } -export function Insight({ messages, title }: { messages: Message[]; title: string }) { +export function Insight({ + messages, + title, + dataTestSubj, +}: { + messages: Message[]; + title: string; + dataTestSubj?: string; +}) { const [hasOpened, setHasOpened] = useState(false); const connectors = useGenAIConnectors(); @@ -322,6 +330,7 @@ export function Insight({ messages, title }: { messages: Message[]; title: strin }} controls={} loading={connectors.loading || chatService.loading} + dataTestSubj={dataTestSubj} > {chatService.value ? ( diff --git a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.tsx b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.tsx index b6c0b4db906b..f288129c7ba9 100644 --- a/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.tsx +++ b/x-pack/plugins/observability_ai_assistant/public/components/insight/insight_base.tsx @@ -32,6 +32,7 @@ export interface InsightBaseProps { onToggle: (isOpen: boolean) => void; children: React.ReactNode; loading?: boolean; + dataTestSubj?: string; } export function InsightBase({ @@ -44,6 +45,7 @@ export function InsightBase({ actions, onToggle, loading, + dataTestSubj = 'obsAiAssistantInsightButton', }: InsightBaseProps) { const { euiTheme } = useEuiTheme(); @@ -59,7 +61,7 @@ export function InsightBase({ id="obsAiAssistantInsight" arrowProps={{ css: { alignSelf: 'flex-start' } }} buttonContent={ - + diff --git a/x-pack/plugins/observability_log_explorer/kibana.jsonc b/x-pack/plugins/observability_log_explorer/kibana.jsonc index 72d03b82d338..92d2ad70c317 100644 --- a/x-pack/plugins/observability_log_explorer/kibana.jsonc +++ b/x-pack/plugins/observability_log_explorer/kibana.jsonc @@ -19,6 +19,7 @@ "observabilityShared", "share", "kibanaUtils", + "datasetQuality" ], "optionalPlugins": [ "serverless" diff --git a/x-pack/plugins/observability_log_explorer/public/applications/observability_log_explorer.tsx b/x-pack/plugins/observability_log_explorer/public/applications/observability_log_explorer.tsx index a8c6602f9d49..8a49db753635 100644 --- a/x-pack/plugins/observability_log_explorer/public/applications/observability_log_explorer.tsx +++ b/x-pack/plugins/observability_log_explorer/public/applications/observability_log_explorer.tsx @@ -10,7 +10,7 @@ import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render'; import { Route, Router, Routes } from '@kbn/shared-ux-router'; import React from 'react'; import ReactDOM from 'react-dom'; -import { ObservablityLogExplorerMainRoute } from '../routes/main'; +import { DatasetQualityRoute, ObservablityLogExplorerMainRoute } from '../routes/main'; import { ObservabilityLogExplorerAppMountParameters, ObservabilityLogExplorerPluginStart, @@ -72,6 +72,11 @@ export const ObservabilityLogExplorerApp = ({ exact={true} render={() => } /> + } + /> diff --git a/x-pack/plugins/observability_log_explorer/public/components/page_template.tsx b/x-pack/plugins/observability_log_explorer/public/components/page_template.tsx index e79b8b1bc627..d128c6e8a777 100644 --- a/x-pack/plugins/observability_log_explorer/public/components/page_template.tsx +++ b/x-pack/plugins/observability_log_explorer/public/components/page_template.tsx @@ -13,10 +13,14 @@ import React from 'react'; export const ObservabilityLogExplorerPageTemplate = ({ children, observabilityShared, + pageProps, }: React.PropsWithChildren<{ observabilityShared: ObservabilitySharedPluginStart; + pageProps?: EuiPageSectionProps; }>) => ( - + {children} ); diff --git a/x-pack/plugins/observability_log_explorer/public/routes/main/dataset_quality_route.tsx b/x-pack/plugins/observability_log_explorer/public/routes/main/dataset_quality_route.tsx new file mode 100644 index 000000000000..b76a462eba25 --- /dev/null +++ b/x-pack/plugins/observability_log_explorer/public/routes/main/dataset_quality_route.tsx @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CoreStart } from '@kbn/core/public'; +import React from 'react'; +import { EuiBreadcrumb } from '@elastic/eui'; +import { datasetQualityAppTitle } from '@kbn/dataset-quality-plugin/public'; +import { ObservabilityLogExplorerPageTemplate } from '../../components/page_template'; +import { useBreadcrumbs } from '../../utils/breadcrumbs'; +import { useKibanaContextForPlugin } from '../../utils/use_kibana'; + +export interface DatasetQualityRouteProps { + core: CoreStart; +} + +export const DatasetQualityRoute = ({ core }: DatasetQualityRouteProps) => { + const { services } = useKibanaContextForPlugin(); + const { observabilityShared, serverless, datasetQuality: DatasetQuality } = services; + const breadcrumb: EuiBreadcrumb[] = [ + { + text: datasetQualityAppTitle, + }, + ]; + + useBreadcrumbs(breadcrumb, core.chrome, serverless); + + return ( + <> + + + + + ); +}; diff --git a/x-pack/plugins/observability_log_explorer/public/routes/main/index.tsx b/x-pack/plugins/observability_log_explorer/public/routes/main/index.tsx index 889e340497cf..9d755f302d16 100644 --- a/x-pack/plugins/observability_log_explorer/public/routes/main/index.tsx +++ b/x-pack/plugins/observability_log_explorer/public/routes/main/index.tsx @@ -6,3 +6,4 @@ */ export * from './main_route'; +export * from './dataset_quality_route'; diff --git a/x-pack/plugins/observability_log_explorer/public/types.ts b/x-pack/plugins/observability_log_explorer/public/types.ts index 8b315ad206ce..5f455088b744 100644 --- a/x-pack/plugins/observability_log_explorer/public/types.ts +++ b/x-pack/plugins/observability_log_explorer/public/types.ts @@ -13,6 +13,7 @@ import { ServerlessPluginStart } from '@kbn/serverless/public'; import { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/public'; import { AppMountParameters, ScopedHistory } from '@kbn/core/public'; import { LogsSharedClientStartExports } from '@kbn/logs-shared-plugin/public'; +import { DatasetQualityPluginStart } from '@kbn/dataset-quality-plugin/public'; import { ObservabilityLogExplorerLocators, ObservabilityLogExplorerLocationState, @@ -38,6 +39,7 @@ export interface ObservabilityLogExplorerStartDeps { observabilityShared: ObservabilitySharedPluginStart; serverless?: ServerlessPluginStart; share: SharePluginStart; + datasetQuality: DatasetQualityPluginStart; } export type ObservabilityLogExplorerHistory = ScopedHistory; diff --git a/x-pack/plugins/observability_log_explorer/tsconfig.json b/x-pack/plugins/observability_log_explorer/tsconfig.json index 109b54b929ec..24327c31c26a 100644 --- a/x-pack/plugins/observability_log_explorer/tsconfig.json +++ b/x-pack/plugins/observability_log_explorer/tsconfig.json @@ -34,7 +34,8 @@ "@kbn/xstate-utils", "@kbn/shared-ux-utility", "@kbn/ui-theme", - "@kbn/logs-shared-plugin" + "@kbn/logs-shared-plugin", + "@kbn/dataset-quality-plugin" ], "exclude": [ "target/**/*" diff --git a/x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx new file mode 100644 index 000000000000..02908cdf67a0 --- /dev/null +++ b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/embeddable_profiling_search_bar.tsx @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { css } from '@emotion/react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { default as React, useEffect, useRef, useState } from 'react'; +import { EMBEDDABLE_PROFILING_SEARCH_BAR } from '.'; +import { ObservabilitySharedStart } from '../../../plugin'; + +export interface EmbeddableProfilingSearchBarProps { + kuery: string; + showDatePicker?: boolean; + onQuerySubmit: (params: { + dateRange: { from: string; to: string; mode?: 'absolute' | 'relative' }; + query: string; + }) => void; + onRefresh: () => void; + rangeFrom: string; + rangeTo: string; +} + +export function EmbeddableProfilingSearchBar(props: EmbeddableProfilingSearchBarProps) { + const { embeddable: embeddablePlugin } = useKibana().services; + const [embeddable, setEmbeddable] = useState(); + const embeddableRoot: React.RefObject = useRef(null); + + useEffect(() => { + async function createEmbeddable() { + const factory = embeddablePlugin?.getEmbeddableFactory(EMBEDDABLE_PROFILING_SEARCH_BAR); + const input = { + id: 'embeddable_profiling', + }; + const embeddableObject = await factory?.create(input); + setEmbeddable(embeddableObject); + } + createEmbeddable(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + if (embeddableRoot.current && embeddable) { + embeddable.render(embeddableRoot.current); + } + }, [embeddable, embeddableRoot]); + + useEffect(() => { + if (embeddable) { + embeddable.updateInput({ + ...props, + }); + embeddable.reload(); + } + }, [embeddable, props]); + + return ( +
    + ); +} diff --git a/x-pack/plugins/observability_shared/public/components/profiling/embeddables/index.ts b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/index.ts index 2e346d55c835..05556b839cff 100644 --- a/x-pack/plugins/observability_shared/public/components/profiling/embeddables/index.ts +++ b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/index.ts @@ -14,3 +14,11 @@ export { EmbeddableFlamegraph } from './embeddable_flamegraph'; export const EMBEDDABLE_FUNCTIONS = 'EMBEDDABLE_FUNCTIONS'; /** Profiling functions embeddable */ export { EmbeddableFunctions } from './embeddable_functions'; + +/** Profiling search bar embeddable key */ +export const EMBEDDABLE_PROFILING_SEARCH_BAR = 'EMBEDDABLE_PROFILING_SEARCH_BAR'; +/** Profiling search bar embeddable */ +export { + EmbeddableProfilingSearchBar, + type EmbeddableProfilingSearchBarProps, +} from './embeddable_profiling_search_bar'; diff --git a/x-pack/plugins/observability_shared/public/components/profiling/embeddables/profiling_embeddable.tsx b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/profiling_embeddable.tsx index 1a703d11ed6c..00f29c10c159 100644 --- a/x-pack/plugins/observability_shared/public/components/profiling/embeddables/profiling_embeddable.tsx +++ b/x-pack/plugins/observability_shared/public/components/profiling/embeddables/profiling_embeddable.tsx @@ -31,7 +31,11 @@ export function ProfilingEmbeddable({ useEffect(() => { async function createEmbeddable() { const factory = embeddablePlugin?.getEmbeddableFactory(embeddableFactoryId); - const input = { id: 'embeddable_profiling', data, isLoading }; + const input = { + id: 'embeddable_profiling', + data, + isLoading, + }; const embeddableObject = await factory?.create(input); setEmbeddable(embeddableObject); } @@ -47,7 +51,11 @@ export function ProfilingEmbeddable({ useEffect(() => { if (embeddable) { - embeddable.updateInput({ data, isLoading, ...props }); + embeddable.updateInput({ + data, + isLoading, + ...props, + }); embeddable.reload(); } }, [data, embeddable, isLoading, props]); diff --git a/x-pack/plugins/observability_shared/public/index.ts b/x-pack/plugins/observability_shared/public/index.ts index 66492328e4b8..cbb59c3d2deb 100644 --- a/x-pack/plugins/observability_shared/public/index.ts +++ b/x-pack/plugins/observability_shared/public/index.ts @@ -83,6 +83,9 @@ export { export { EMBEDDABLE_FLAMEGRAPH, EMBEDDABLE_FUNCTIONS, + EMBEDDABLE_PROFILING_SEARCH_BAR, EmbeddableFlamegraph, EmbeddableFunctions, + EmbeddableProfilingSearchBar, + type EmbeddableProfilingSearchBarProps, } from './components/profiling/embeddables'; diff --git a/x-pack/plugins/osquery/public/form/timeout_field.tsx b/x-pack/plugins/osquery/public/form/timeout_field.tsx index a9ad26d11e17..5ef6627ba2c4 100644 --- a/x-pack/plugins/osquery/public/form/timeout_field.tsx +++ b/x-pack/plugins/osquery/public/form/timeout_field.tsx @@ -8,14 +8,7 @@ import React, { useCallback, useMemo } from 'react'; import deepEqual from 'fast-deep-equal'; import { useController } from 'react-hook-form'; import type { EuiFieldNumberProps } from '@elastic/eui'; -import { - EuiFieldNumber, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiIconTip, - EuiText, -} from '@elastic/eui'; +import { EuiFieldNumber, EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiIconTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -81,16 +74,6 @@ const TimeoutFieldComponent = ({ euiFieldProps }: TimeoutFieldProps) => { fullWidth error={error?.message} isInvalid={hasError} - labelAppend={ - - - - - - } > { }); cy.wait('@getTopNFunctions'); cy.wait('@getTopNFunctions'); - cy.get('[data-test-subj="topNFunctionsGrid"] .euiDataGridRow').should('have.length.gt', 1); - cy.get('[data-test-subj="TopNFunctionsComparisonGrid"] .euiDataGridRow').should( - 'have.length.gt', - 1 - ); - cy.get( - '[data-test-subj="topNFunctionsGrid"] [data-test-subj="profilingStackFrameSummaryLink"]' - ).contains('vmlinux'); - cy.get( - '[data-test-subj="TopNFunctionsComparisonGrid"] [data-test-subj="profilingStackFrameSummaryLink"]' - ).contains('vmlinux'); + cy.get('[data-test-subj="frame"]').contains('vmlinux'); + cy.get('[data-test-subj="comparison_frame"]').contains('vmlinux'); cy.addKqlFilter({ key: 'process.thread.name', @@ -190,12 +181,8 @@ describe('Differential Functions page', () => { }); cy.wait('@getTopNFunctions'); cy.wait('@getTopNFunctions'); - cy.get( - '[data-test-subj="topNFunctionsGrid"] [data-test-subj="profilingStackFrameSummaryLink"]' - ).contains('libsystemd-shared-237.so'); - cy.get( - '[data-test-subj="TopNFunctionsComparisonGrid"] [data-test-subj="profilingStackFrameSummaryLink"]' - ).contains('libjvm.so'); + cy.get('[data-test-subj="frame"]').contains('libsystemd-shared-237.so'); + cy.get('[data-test-subj="comparison_frame"]').contains('libjvm.so'); }); }); }); diff --git a/x-pack/plugins/profiling/public/components/contexts/profiling_dependencies/mock_profiling_dependencies_storybook.tsx b/x-pack/plugins/profiling/public/components/contexts/profiling_dependencies/mock_profiling_dependencies_storybook.tsx index 9e4ebc0afeae..3508f3f090c6 100644 --- a/x-pack/plugins/profiling/public/components/contexts/profiling_dependencies/mock_profiling_dependencies_storybook.tsx +++ b/x-pack/plugins/profiling/public/components/contexts/profiling_dependencies/mock_profiling_dependencies_storybook.tsx @@ -43,6 +43,7 @@ const mockPlugin = { }; const mockCore = { + uiSettings: { get: () => {} }, application: { currentAppId$: new Observable(), getUrlForApp: (appId: string) => '', diff --git a/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_columns.tsx b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_columns.tsx new file mode 100644 index 000000000000..71ead9cd75a8 --- /dev/null +++ b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_columns.tsx @@ -0,0 +1,129 @@ +/* + * 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 { EuiDataGridColumn, EuiDataGridColumnCellAction } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { TopNComparisonFunctionSortField, TopNFunctionSortField } from '@kbn/profiling-utils'; +import React from 'react'; +import { CPULabelWithHint } from '../cpu_label_with_hint'; +import { LabelWithHint } from '../label_with_hint'; + +export const getColumns = ( + compareFrameAction: EuiDataGridColumnCellAction +): EuiDataGridColumn[] => [ + { + id: TopNFunctionSortField.Rank, + actions: { showHide: false }, + displayAsText: 'Rank', + initialWidth: 65, + schema: 'numeric', + }, + { + id: TopNFunctionSortField.Frame, + actions: { showHide: false }, + displayAsText: i18n.translate('xpack.profiling.functionsView.functionColumnLabel', { + defaultMessage: 'Function', + }), + cellActions: [compareFrameAction], + }, + { + id: TopNFunctionSortField.Samples, + initialWidth: 120, + schema: 'numeric', + actions: { showHide: false }, + display: ( + + ), + }, + { + id: TopNFunctionSortField.SelfCPU, + actions: { showHide: false }, + schema: 'numeric', + initialWidth: 120, + display: ( + + ), + }, + { + id: TopNFunctionSortField.TotalCPU, + actions: { showHide: false }, + schema: 'numeric', + initialWidth: 120, + display: ( + + ), + }, + { + id: TopNComparisonFunctionSortField.ComparisonRank, + actions: { showHide: false }, + schema: 'numeric', + displayAsText: 'Rank', + initialWidth: 69, + displayHeaderCellProps: { className: 'thickBorderLeft' }, + }, + { + id: TopNComparisonFunctionSortField.ComparisonFrame, + actions: { showHide: false }, + displayAsText: i18n.translate('xpack.profiling.functionsView.functionColumnLabel', { + defaultMessage: 'Function', + }), + cellActions: [compareFrameAction], + }, + { + id: TopNComparisonFunctionSortField.ComparisonSamples, + actions: { showHide: false }, + schema: 'numeric', + initialWidth: 120, + display: ( + + ), + }, + { + id: TopNComparisonFunctionSortField.ComparisonSelfCPU, + actions: { showHide: false }, + schema: 'numeric', + initialWidth: 120, + display: ( + + ), + }, + { + id: TopNComparisonFunctionSortField.ComparisonTotalCPU, + actions: { showHide: false }, + schema: 'numeric', + initialWidth: 120, + display: ( + + ), + }, + { + displayAsText: 'Diff', + actions: { showHide: false }, + id: TopNComparisonFunctionSortField.ComparisonDiff, + initialWidth: 70, + isSortable: false, + }, +]; diff --git a/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_compare_frame_action.tsx b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_compare_frame_action.tsx new file mode 100644 index 000000000000..32f6bc826d98 --- /dev/null +++ b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/get_compare_frame_action.tsx @@ -0,0 +1,121 @@ +/* + * 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 { + EuiBasicTable, + EuiDataGridColumnCellAction, + EuiDataGridColumnCellActionProps, + EuiPopover, + EuiPopoverTitle, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import React from 'react'; +import { i18n } from '@kbn/i18n'; +import { css } from '@emotion/react'; +import { getCalleeFunction } from '@kbn/profiling-utils'; +import { getFrameIdentification, isComparisonColumn, SelectedFrame } from '.'; +import { IFunctionRow } from '../topn_functions/utils'; + +interface Props { + baseRows: IFunctionRow[]; + comparisonRows: IFunctionRow[]; + selectedFrame?: SelectedFrame; + onClick: (selectedFrame?: SelectedFrame) => void; +} + +export const getCompareFrameAction = + ({ baseRows, comparisonRows, selectedFrame, onClick }: Props): EuiDataGridColumnCellAction => + ({ rowIndex, columnId, Component }: EuiDataGridColumnCellActionProps) => { + const isComparison = isComparisonColumn(columnId); + const currentRow = isComparison ? comparisonRows[rowIndex] : baseRows[rowIndex]; + if (currentRow === undefined) { + return null; + } + const currentFrameId = getFrameIdentification(currentRow.frame); + + const isOpen = selectedFrame + ? selectedFrame.currentFrameId === currentFrameId && + selectedFrame.isComparison === isComparison + : false; + + const compareRow = isComparison + ? baseRows.find((item) => getFrameIdentification(item.frame) === currentFrameId) + : comparisonRows.find((item) => getFrameIdentification(item.frame) === currentFrameId); + + return ( + { + onClick({ currentFrameId, isComparison }); + }} + iconType="inspect" + > + {i18n.translate('xpack.profiling.compareFrame.component.findLabel', { + defaultMessage: 'Find corresponding frame', + })} + + } + isOpen={isOpen} + closePopover={() => { + onClick(undefined); + }} + anchorPosition="upRight" + css={css` + .euiPopover__anchor { + align-items: start; + display: flex; + } + `} + > + {compareRow ? ( +
    + + {isComparison + ? i18n.translate('xpack.profiling.diffTopNFunctions.baseLineFunction', { + defaultMessage: 'Baseline function', + }) + : i18n.translate('xpack.profiling.diffTopNFunctions.comparisonLineFunction', { + defaultMessage: 'Comparison function', + })} + + + {getCalleeFunction(compareRow.frame)} + + value.samples.toLocaleString(), + }, + { + field: 'selfCPUPerc', + name: 'Self CPU', + render: (_, value) => `${value.selfCPUPerc.toFixed(2)}%`, + }, + { + field: 'totalCPUPerc', + name: 'Total CPU', + render: (_, value) => `${value.totalCPUPerc.toFixed(2)}%`, + }, + ]} + /> +
    + ) : ( + + {i18n.translate('xpack.profiling.diffTopNFunctions.noCorrespondingValueFound', { + defaultMessage: 'No corresponding value found', + })} + + )} +
    + ); + }; diff --git a/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx new file mode 100644 index 000000000000..a006a4724a9b --- /dev/null +++ b/x-pack/plugins/profiling/public/components/differential_topn_functions_grid/index.tsx @@ -0,0 +1,265 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiDataGrid, + EuiDataGridCellValueElementProps, + EuiDataGridColumn, + EuiDataGridSorting, + useEuiTheme, +} from '@elastic/eui'; +import { css } from '@emotion/react'; +import { i18n } from '@kbn/i18n'; +import { + getCalleeFunction, + StackFrameMetadata, + TopNComparisonFunctionSortField, + TopNFunctions, + TopNFunctionSortField, +} from '@kbn/profiling-utils'; +import { orderBy } from 'lodash'; +import React, { useEffect, useMemo, useState } from 'react'; +import { useCalculateImpactEstimate } from '../../hooks/use_calculate_impact_estimates'; +import { FunctionRow } from '../topn_functions/function_row'; +import { getFunctionsRows, IFunctionRow } from '../topn_functions/utils'; +import { getColumns } from './get_columns'; +import { getCompareFrameAction } from './get_compare_frame_action'; + +const removeComparisonFromId = (id: string) => id.replace('comparison_', ''); +export const isComparisonColumn = (id: string) => id.startsWith('comparison_'); + +type SortDirection = 'asc' | 'desc'; + +function sortRows(data: IFunctionRow[], sortField: string, sortDirection: SortDirection) { + switch (sortField) { + case TopNFunctionSortField.Frame: + return orderBy(data, (row) => getCalleeFunction(row.frame), sortDirection); + case TopNFunctionSortField.SelfCPU: + return orderBy(data, (row) => row.selfCPUPerc, sortDirection); + case TopNFunctionSortField.TotalCPU: + return orderBy(data, (row) => row.totalCPUPerc, sortDirection); + default: + return orderBy(data, sortField, sortDirection); + } +} + +export type OnChangeSortParams = + | { sortField: TopNFunctionSortField; sortDirection: SortDirection } + | { + comparisonSortField: TopNComparisonFunctionSortField; + comparisonSortDirection: SortDirection; + }; + +export function getFrameIdentification(frame: StackFrameMetadata) { + return [ + frame.SourceFilename, + frame.FunctionName, + frame.ExeFileName, + frame.FileID, + frame.AddressOrLine, + ].join('|'); +} + +export interface SelectedFrame { + currentFrameId?: string; + isComparison: boolean; +} + +interface Props { + base?: TopNFunctions; + baselineScaleFactor?: number; + comparison?: TopNFunctions; + comparisonScaleFactor?: number; + onChangePage: (nextPage: number) => void; + onChangeSort: (sorting: OnChangeSortParams) => void; + onFrameClick?: (functionName: string) => void; + pageIndex: number; + sortDirection: 'asc' | 'desc'; + sortField: TopNFunctionSortField; + comparisonSortDirection: 'asc' | 'desc'; + comparisonSortField: TopNComparisonFunctionSortField; + totalSeconds: number; +} + +export function DifferentialTopNFunctionsGrid({ + base, + baselineScaleFactor, + comparison, + comparisonScaleFactor, + onChangePage, + onChangeSort, + pageIndex, + sortDirection, + sortField, + totalSeconds, + onFrameClick, + comparisonSortDirection, + comparisonSortField, +}: Props) { + const calculateImpactEstimates = useCalculateImpactEstimate(); + const [selectedFrame, setSelectedFrame] = useState(); + const theme = useEuiTheme(); + + const totalCount = useMemo(() => { + if (!base || !base.TotalCount) { + return 0; + } + + return base.TotalCount; + }, [base]); + + function onSort(newSortingColumns: EuiDataGridSorting['columns']) { + // As newSortingColumns is an array and we only sort by a single field for both base and comparison + // I need to look for the item that is not the same as in the URL to identify what's the side being sorted. + const sortingItem = newSortingColumns.reverse().find((item) => { + const isComparison = isComparisonColumn(item.id); + if (isComparison) { + return !(comparisonSortField === item.id && comparisonSortDirection === item.direction); + } + return !(sortField === item.id && sortDirection === item.direction); + }); + if (sortingItem) { + const isComparison = isComparisonColumn(sortingItem.id); + onChangeSort( + isComparison + ? { + comparisonSortDirection: sortingItem.direction, + comparisonSortField: sortingItem.id as TopNComparisonFunctionSortField, + } + : { + sortDirection: sortingItem.direction, + sortField: sortingItem.id as TopNFunctionSortField, + } + ); + } + } + + const { baseRows, comparisonRows } = useMemo(() => { + return { + baseRows: getFunctionsRows({ + calculateImpactEstimates, + topNFunctions: base, + totalSeconds: 900, + }), + comparisonRows: getFunctionsRows({ + baselineScaleFactor, + calculateImpactEstimates, + comparisonScaleFactor, + comparisonTopNFunctions: base, + topNFunctions: comparison, + totalSeconds, + }), + }; + }, [ + base, + baselineScaleFactor, + calculateImpactEstimates, + comparison, + comparisonScaleFactor, + totalSeconds, + ]); + + const columns: EuiDataGridColumn[] = useMemo(() => { + const compareFrameAction = getCompareFrameAction({ + baseRows, + comparisonRows, + onClick: setSelectedFrame, + selectedFrame, + }); + return getColumns(compareFrameAction); + }, [baseRows, comparisonRows, selectedFrame]); + + const sortedBaseRows = useMemo(() => { + return sortRows(baseRows, sortField, sortDirection); + }, [baseRows, sortDirection, sortField]); + + const sortedComparisonRows = useMemo(() => { + return sortRows( + comparisonRows, + removeComparisonFromId(comparisonSortField), + comparisonSortDirection + ); + }, [comparisonRows, comparisonSortDirection, comparisonSortField]); + + const [visibleColumns, setVisibleColumns] = useState(columns.map(({ id }) => id)); + + function CellValue({ rowIndex, columnId, setCellProps }: EuiDataGridCellValueElementProps) { + const isComparison = isComparisonColumn(columnId); + const data = isComparison ? sortedComparisonRows[rowIndex] : sortedBaseRows[rowIndex]; + + useEffect(() => { + // Add thick border to divide the baseline and comparison columns + if (isComparison && columnId === TopNComparisonFunctionSortField.ComparisonRank) { + setCellProps({ + style: { borderLeft: theme.euiTheme.border.thick }, + }); + } else if (columnId === TopNFunctionSortField.TotalCPU) { + setCellProps({ + style: { borderRight: theme.euiTheme.border.thin }, + }); + } + }, [columnId, isComparison, setCellProps]); + + if (data === undefined) { + return null; + } + + return ( +
    + +
    + ); + } + + const rowCount = Math.min(Math.max(sortedBaseRows.length, sortedComparisonRows.length), 100); + + return ( + {}, + onChangePage, + pageSizeOptions: [], + }} + rowHeightsOptions={{ defaultHeight: 'auto' }} + toolbarVisibility={{ + showColumnSelector: false, + showKeyboardShortcuts: false, + showDisplaySelector: false, + showSortSelector: false, + }} + /> + ); +} diff --git a/x-pack/plugins/profiling/public/components/profiling_app_page_template/profiling_search_bar.tsx b/x-pack/plugins/profiling/public/components/profiling_app_page_template/profiling_search_bar.tsx index f1c52e6db5d0..c41468f5dbff 100644 --- a/x-pack/plugins/profiling/public/components/profiling_app_page_template/profiling_search_bar.tsx +++ b/x-pack/plugins/profiling/public/components/profiling_app_page_template/profiling_search_bar.tsx @@ -12,19 +12,10 @@ import React, { useEffect, useState } from 'react'; import { INDEX_EVENTS } from '../../../common'; import { useProfilingDependencies } from '../contexts/profiling_dependencies/use_profiling_dependencies'; -export function ProfilingSearchBar({ - kuery, - rangeFrom, - rangeTo, - onQuerySubmit, - onRefresh, - onRefreshClick, - showSubmitButton = true, - dataTestSubj = 'profilingUnifiedSearchBar', -}: { +interface Props { kuery: string; - rangeFrom: string; - rangeTo: string; + rangeFrom?: string; + rangeTo?: string; onQuerySubmit: ( payload: { dateRange: TimeRange; @@ -32,11 +23,26 @@ export function ProfilingSearchBar({ }, isUpdate?: boolean ) => void; - onRefresh: Required>['onRefresh']; + onRefresh?: Required>['onRefresh']; onRefreshClick: () => void; showSubmitButton?: boolean; dataTestSubj?: string; -}) { + showDatePicker?: boolean; + showQueryMenu?: boolean; +} + +export function ProfilingSearchBar({ + kuery, + rangeFrom, + rangeTo, + onQuerySubmit, + onRefresh, + onRefreshClick, + showSubmitButton = true, + dataTestSubj = 'profilingUnifiedSearchBar', + showDatePicker = true, + showQueryMenu = true, +}: Props) { const { start: { dataViews }, } = useProfilingDependencies(); @@ -67,7 +73,7 @@ export function ProfilingSearchBar({ onQuerySubmit({ dateRange, query }); }} showQueryInput - showDatePicker + showDatePicker={showDatePicker} showFilterBar={false} showSaveQuery={false} submitButtonStyle={!showSubmitButton ? 'iconOnly' : 'auto'} @@ -78,6 +84,7 @@ export function ProfilingSearchBar({ onRefresh={onRefresh} displayStyle="inPage" dataTestSubj={dataTestSubj} + showQueryMenu={showQueryMenu} /> ); } diff --git a/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx b/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx index 6cf0159dcdc0..d2421e704ac0 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx +++ b/x-pack/plugins/profiling/public/components/topn_functions/function_row.tsx @@ -112,7 +112,7 @@ function DiffColumn({ diff, setCellProps }: DiffColumnProps) { const dangerColor = useEuiBackgroundColor('danger'); useEffect(() => { - if (diff && diff.rank > 0) { + if (diff && diff.rank !== 0) { const color = diff.rank > 0 ? 'success' : 'danger'; setCellProps({ style: { backgroundColor: color === 'success' ? successColor : dangerColor }, diff --git a/x-pack/plugins/profiling/public/components/topn_functions/utils.ts b/x-pack/plugins/profiling/public/components/topn_functions/utils.ts index 788c7397fa79..e09b404b5c60 100644 --- a/x-pack/plugins/profiling/public/components/topn_functions/utils.ts +++ b/x-pack/plugins/profiling/public/components/topn_functions/utils.ts @@ -33,6 +33,7 @@ export function scaleValue({ value, scaleFactor = 1 }: { value: number; scaleFac } export interface IFunctionRow { + id: string; rank: number; frame: StackFrameMetadata; samples: number; @@ -106,6 +107,7 @@ export function getFunctionsRows({ const scaledDiffSamples = scaledSelfCPU - comparisonScaledSelfCPU; return { + id: comparisonRow.Id, rank: topN.Rank - comparisonRow.Rank, samples: scaledDiffSamples, selfCPU: comparisonRow.CountExclusive, @@ -120,6 +122,7 @@ export function getFunctionsRows({ } return { + id: topN.Id, rank: topN.Rank, frame: topN.Frame, samples: scaledSelfCPU, diff --git a/x-pack/plugins/profiling/public/embeddables/functions/embeddable_functions.tsx b/x-pack/plugins/profiling/public/embeddables/functions/embeddable_functions.tsx index 4cfbe7ceddbb..9a198ae66e26 100644 --- a/x-pack/plugins/profiling/public/embeddables/functions/embeddable_functions.tsx +++ b/x-pack/plugins/profiling/public/embeddables/functions/embeddable_functions.tsx @@ -9,12 +9,12 @@ import { EMBEDDABLE_FUNCTIONS } from '@kbn/observability-shared-plugin/public'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { AsyncEmbeddableComponent } from '../async_embeddable_component'; -import { EmbeddableFunctionsEmbeddableInput } from './embeddable_functions_factory'; -import { EmbeddableFunctionsGrid } from './embeddable_functions_grid'; import { ProfilingEmbeddableProvider, ProfilingEmbeddablesDependencies, } from '../profiling_embeddable_provider'; +import { EmbeddableFunctionsEmbeddableInput } from './embeddable_functions_factory'; +import { EmbeddableFunctionsGrid } from './embeddable_functions_grid'; export class EmbeddableFunctions extends Embeddable< EmbeddableFunctionsEmbeddableInput, diff --git a/x-pack/plugins/profiling/public/embeddables/profiling_embeddable_provider.tsx b/x-pack/plugins/profiling/public/embeddables/profiling_embeddable_provider.tsx index d4db1e2d9fb7..b8defbdfa4ac 100644 --- a/x-pack/plugins/profiling/public/embeddables/profiling_embeddable_provider.tsx +++ b/x-pack/plugins/profiling/public/embeddables/profiling_embeddable_provider.tsx @@ -9,6 +9,7 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { ObservabilityAIAssistantProvider } from '@kbn/observability-ai-assistant-plugin/public'; import React, { ReactChild, useMemo } from 'react'; import { CoreSetup, CoreStart } from '@kbn/core/public'; +import { Storage } from '@kbn/kibana-utils-plugin/public'; import { ProfilingDependenciesContextProvider } from '../components/contexts/profiling_dependencies/profiling_dependencies_context'; import { ProfilingPluginPublicSetupDeps, ProfilingPluginPublicStartDeps } from '../types'; import { Services } from '../services'; @@ -21,6 +22,8 @@ export interface ProfilingEmbeddablesDependencies { profilingFetchServices: Services; } +const storage = new Storage(localStorage); + export type GetProfilingEmbeddableDependencies = () => Promise; interface Props { @@ -44,13 +47,17 @@ export function ProfilingEmbeddableProvider({ deps, children }: Props) { [deps] ); + const i18nCore = deps.coreStart.i18n; + return ( - - - - {children} - - - + + + + + {children} + + + + ); } diff --git a/x-pack/plugins/profiling/public/embeddables/register_embeddables.ts b/x-pack/plugins/profiling/public/embeddables/register_embeddables.ts index d7b2e947144b..2c229414960a 100644 --- a/x-pack/plugins/profiling/public/embeddables/register_embeddables.ts +++ b/x-pack/plugins/profiling/public/embeddables/register_embeddables.ts @@ -9,10 +9,12 @@ import { EmbeddableSetup } from '@kbn/embeddable-plugin/public'; import { EMBEDDABLE_FLAMEGRAPH, EMBEDDABLE_FUNCTIONS, + EMBEDDABLE_PROFILING_SEARCH_BAR, } from '@kbn/observability-shared-plugin/public'; import { EmbeddableFlamegraphFactory } from './flamegraph/embeddable_flamegraph_factory'; import { EmbeddableFunctionsFactory } from './functions/embeddable_functions_factory'; import { GetProfilingEmbeddableDependencies } from './profiling_embeddable_provider'; +import { EmbeddableSearchBarFactory } from './search_bar/embeddable_search_bar_factory'; export function registerEmbeddables( embeddable: EmbeddableSetup, @@ -26,4 +28,8 @@ export function registerEmbeddables( EMBEDDABLE_FUNCTIONS, new EmbeddableFunctionsFactory(getProfilingEmbeddableDependencies) ); + embeddable.registerEmbeddableFactory( + EMBEDDABLE_PROFILING_SEARCH_BAR, + new EmbeddableSearchBarFactory(getProfilingEmbeddableDependencies) + ); } diff --git a/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar.tsx b/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar.tsx new file mode 100644 index 000000000000..cbc773abfc0f --- /dev/null +++ b/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar.tsx @@ -0,0 +1,78 @@ +/* + * 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 { css } from '@emotion/react'; +import { Embeddable, EmbeddableOutput, IContainer } from '@kbn/embeddable-plugin/public'; +import { EMBEDDABLE_PROFILING_SEARCH_BAR } from '@kbn/observability-shared-plugin/public'; +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; +import { ProfilingSearchBar } from '../../components/profiling_app_page_template/profiling_search_bar'; +import { + ProfilingEmbeddableProvider, + ProfilingEmbeddablesDependencies, +} from '../profiling_embeddable_provider'; +import { EmbeddableSearchBarEmbeddableInput } from './embeddable_search_bar_factory'; + +export class EmbeddableSearchBar extends Embeddable< + EmbeddableSearchBarEmbeddableInput, + EmbeddableOutput +> { + readonly type = EMBEDDABLE_PROFILING_SEARCH_BAR; + private _domNode?: HTMLElement; + + constructor( + private deps: ProfilingEmbeddablesDependencies, + initialInput: EmbeddableSearchBarEmbeddableInput, + parent?: IContainer + ) { + super(initialInput, {}, parent); + } + + render(domNode: HTMLElement) { + this._domNode = domNode; + const { showDatePicker, kuery, onQuerySubmit, onRefresh, rangeFrom, rangeTo } = this.input; + + render( + +
    + { + onQuerySubmit({ + dateRange, + query: typeof query?.query === 'string' ? query.query : '', + }); + }} + onRefresh={onRefresh} + onRefreshClick={onRefresh} + showQueryMenu={false} + rangeFrom={rangeFrom} + rangeTo={rangeTo} + /> +
    +
    , + domNode + ); + } + + public destroy() { + if (this._domNode) { + unmountComponentAtNode(this._domNode); + } + } + + reload() { + if (this._domNode) { + this.render(this._domNode); + } + } +} diff --git a/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar_factory.ts b/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar_factory.ts new file mode 100644 index 000000000000..cc7443976e1b --- /dev/null +++ b/x-pack/plugins/profiling/public/embeddables/search_bar/embeddable_search_bar_factory.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { + EmbeddableFactoryDefinition, + EmbeddableInput, + IContainer, +} from '@kbn/embeddable-plugin/public'; +import { + EmbeddableProfilingSearchBarProps, + EMBEDDABLE_PROFILING_SEARCH_BAR, +} from '@kbn/observability-shared-plugin/public'; +import type { GetProfilingEmbeddableDependencies } from '../profiling_embeddable_provider'; + +export type EmbeddableSearchBarEmbeddableInput = EmbeddableProfilingSearchBarProps & + EmbeddableInput; + +export class EmbeddableSearchBarFactory + implements EmbeddableFactoryDefinition +{ + readonly type = EMBEDDABLE_PROFILING_SEARCH_BAR; + + constructor(private getProfilingEmbeddableDependencies: GetProfilingEmbeddableDependencies) {} + + async isEditable() { + return false; + } + + async create(input: EmbeddableSearchBarEmbeddableInput, parent?: IContainer) { + const { EmbeddableSearchBar } = await import('./embeddable_search_bar'); + const deps = await this.getProfilingEmbeddableDependencies(); + return new EmbeddableSearchBar(deps, input, parent); + } + + getDisplayName() { + return 'Universal Profiling Search bar'; + } +} diff --git a/x-pack/plugins/profiling/public/routing/index.tsx b/x-pack/plugins/profiling/public/routing/index.tsx index cb92422a9407..9df36e393c38 100644 --- a/x-pack/plugins/profiling/public/routing/index.tsx +++ b/x-pack/plugins/profiling/public/routing/index.tsx @@ -6,33 +6,35 @@ */ import { i18n } from '@kbn/i18n'; import { toNumberRt } from '@kbn/io-ts-utils'; -import { createRouter, Outlet } from '@kbn/typed-react-router-config'; -import * as t from 'io-ts'; -import React from 'react'; import { StackTracesDisplayOption, - TopNType, + TopNComparisonFunctionSortField, + topNComparisonFunctionSortFieldRt, TopNFunctionSortField, topNFunctionSortFieldRt, + TopNType, } from '@kbn/profiling-utils'; +import { createRouter, Outlet } from '@kbn/typed-react-router-config'; +import * as t from 'io-ts'; +import React from 'react'; import { indexLifecyclePhaseRt, IndexLifecyclePhaseSelectOption, } from '../../common/storage_explorer'; import { ComparisonMode, NormalizationMode } from '../components/normalization_menu'; import { RedirectTo } from '../components/redirect_to'; +import { AddDataTabs, AddDataView } from '../views/add_data_view'; +import { DeleteDataView } from '../views/delete_data_view'; import { FlameGraphsView } from '../views/flamegraphs'; import { DifferentialFlameGraphsView } from '../views/flamegraphs/differential_flamegraphs'; import { FlameGraphView } from '../views/flamegraphs/flamegraph'; import { FunctionsView } from '../views/functions'; import { DifferentialTopNFunctionsView } from '../views/functions/differential_topn'; import { TopNFunctionsView } from '../views/functions/topn'; -import { AddDataTabs, AddDataView } from '../views/add_data_view'; +import { Settings } from '../views/settings'; import { StackTracesView } from '../views/stack_traces_view'; import { StorageExplorerView } from '../views/storage_explorer'; import { RouteBreadcrumb } from './route_breadcrumb'; -import { DeleteDataView } from '../views/delete_data_view'; -import { Settings } from '../views/settings'; const routes = { '/settings': { @@ -253,6 +255,8 @@ const routes = { t.literal(NormalizationMode.Scale), t.literal(NormalizationMode.Time), ]), + comparisonSortField: topNComparisonFunctionSortFieldRt, + comparisonSortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), t.partial({ baseline: toNumberRt, @@ -267,6 +271,8 @@ const routes = { comparisonRangeTo: 'now', comparisonKuery: '', normalizationMode: NormalizationMode.Time, + comparisonSortField: TopNComparisonFunctionSortField.ComparisonRank, + comparisonSortDirection: 'asc', }, }, }, diff --git a/x-pack/plugins/profiling/public/types.ts b/x-pack/plugins/profiling/public/types.ts index e583a4962dc6..cc949254e270 100644 --- a/x-pack/plugins/profiling/public/types.ts +++ b/x-pack/plugins/profiling/public/types.ts @@ -25,6 +25,10 @@ import { ObservabilityAIAssistantPluginStart, } from '@kbn/observability-ai-assistant-plugin/public'; import { EmbeddableSetup } from '@kbn/embeddable-plugin/public'; +import type { + UnifiedSearchPublicPluginStart, + UnifiedSearchPluginSetup, +} from '@kbn/unified-search-plugin/public'; export interface ProfilingPluginPublicSetupDeps { observability: ObservabilityPublicSetup; @@ -36,6 +40,7 @@ export interface ProfilingPluginPublicSetupDeps { licensing: LicensingPluginSetup; share: SharePluginSetup; embeddable: EmbeddableSetup; + unifiedSearch: UnifiedSearchPluginSetup; } export interface ProfilingPluginPublicStartDeps { @@ -46,4 +51,5 @@ export interface ProfilingPluginPublicStartDeps { data: DataPublicPluginStart; charts: ChartsPluginStart; share: SharePluginStart; + unifiedSearch: UnifiedSearchPublicPluginStart; } diff --git a/x-pack/plugins/profiling/public/views/add_data_view/index.tsx b/x-pack/plugins/profiling/public/views/add_data_view/index.tsx index 556e29c1ba24..27e3ac639757 100644 --- a/x-pack/plugins/profiling/public/views/add_data_view/index.tsx +++ b/x-pack/plugins/profiling/public/views/add_data_view/index.tsx @@ -541,7 +541,7 @@ docker.elastic.co/observability/profiling-agent:${stackVersion} /root/pf-host-ag title={ diff --git a/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx b/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx index cf538642afce..0c5c45f60fcb 100644 --- a/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx +++ b/x-pack/plugins/profiling/public/views/functions/differential_topn/index.tsx @@ -4,28 +4,21 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { - EuiDataGridRefProps, - EuiDataGridSorting, - EuiFlexGroup, - EuiFlexItem, - EuiHorizontalRule, - EuiPanel, - EuiSpacer, -} from '@elastic/eui'; -import { TopNFunctionSortField } from '@kbn/profiling-utils'; -import React, { useRef } from 'react'; -import { GridOnScrollProps } from 'react-window'; +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel, EuiSpacer } from '@elastic/eui'; +import React from 'react'; import { AsyncComponent } from '../../../components/async_component'; import { useProfilingDependencies } from '../../../components/contexts/profiling_dependencies/use_profiling_dependencies'; import { FramesSummary } from '../../../components/frames_summary'; +import { + DifferentialTopNFunctionsGrid, + OnChangeSortParams, +} from '../../../components/differential_topn_functions_grid'; import { NormalizationMenu, NormalizationMode, NormalizationOptions, } from '../../../components/normalization_menu'; import { PrimaryAndComparisonSearchBar } from '../../../components/primary_and_comparison_search_bar'; -import { TopNFunctionsGrid } from '../../../components/topn_functions'; import { AsyncStatus } from '../../../hooks/use_async'; import { useProfilingParams } from '../../../hooks/use_profiling_params'; import { useProfilingRouter } from '../../../hooks/use_profiling_router'; @@ -34,8 +27,6 @@ import { useTimeRange } from '../../../hooks/use_time_range'; import { useTimeRangeAsync } from '../../../hooks/use_time_range_async'; export function DifferentialTopNFunctionsView() { - const baseGridRef = useRef(null); - const comparisonGridRef = useRef(null); const { query } = useProfilingParams('/functions/differential'); const { rangeFrom, @@ -50,6 +41,8 @@ export function DifferentialTopNFunctionsView() { baseline = 1, comparison = 1, pageIndex = 0, + comparisonSortDirection, + comparisonSortField, } = query; const timeRange = useTimeRange({ rangeFrom, rangeTo }); @@ -147,20 +140,6 @@ export function DifferentialTopNFunctionsView() { }); } - function handleBaseGridScroll(scroll: GridOnScrollProps) { - if (comparisonGridRef?.current?.scrollTo) { - comparisonGridRef.current.scrollTo({ - scrollTop: scroll.scrollTop, - }); - } - } - - function handleComparisonGridScroll(scroll: GridOnScrollProps) { - if (baseGridRef?.current?.scrollTo) { - baseGridRef.current.scrollTo({ scrollTop: scroll.scrollTop }); - } - } - function handlePageChange(nextPage: number) { profilingRouter.push('/functions/differential', { path: {}, @@ -168,14 +147,10 @@ export function DifferentialTopNFunctionsView() { }); } - function handleSortChange(sorting: EuiDataGridSorting['columns'][0]) { + function handleOnSort(sorting: OnChangeSortParams) { profilingRouter.push('/functions/differential', { path: {}, - query: { - ...query, - sortField: sorting.id as TopNFunctionSortField, - sortDirection: sorting.direction, - }, + query: { ...query, ...sorting }, }); } @@ -223,50 +198,27 @@ export function DifferentialTopNFunctionsView() { - - - - - - - {comparisonTimeRange.inSeconds.start && comparisonTimeRange.inSeconds.end ? ( - - - - - - ) : null} - + + + diff --git a/x-pack/plugins/profiling/public/views/functions/index.tsx b/x-pack/plugins/profiling/public/views/functions/index.tsx index 1131056d9a9b..2e4ddb32bc03 100644 --- a/x-pack/plugins/profiling/public/views/functions/index.tsx +++ b/x-pack/plugins/profiling/public/views/functions/index.tsx @@ -8,6 +8,7 @@ import { EuiPageHeaderContentProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { TopNComparisonFunctionSortField } from '@kbn/profiling-utils'; import { NormalizationMode } from '../../components/normalization_menu'; import { ProfilingAppPageTemplate } from '../../components/profiling_app_page_template'; import { RedirectTo } from '../../components/redirect_to'; @@ -51,6 +52,12 @@ export function FunctionsView({ children }: { children: React.ReactElement }) { comparisonKuery: query.kuery, normalizationMode: 'normalizationMode' in query ? query.normalizationMode : NormalizationMode.Time, + comparisonSortField: + 'comparisonSortField' in query + ? query.comparisonSortField + : TopNComparisonFunctionSortField.ComparisonRank, + comparisonSortDirection: + 'comparisonSortDirection' in query ? query.comparisonSortDirection : 'asc', }, }), }, diff --git a/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_setup_trust/confirm_modal.tsx b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_setup_trust/confirm_modal.tsx index 08ef4377338d..1d9e9f1900f0 100644 --- a/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_setup_trust/confirm_modal.tsx +++ b/x-pack/plugins/remote_clusters/public/application/sections/components/remote_cluster_setup_trust/confirm_modal.tsx @@ -70,6 +70,9 @@ export const ConfirmTrustSetupModal = ({ closeModal, onSubmit }: ModalProps) => label={i18n.translate('xpack.remoteClusters.clusterWizard.trustStep.modal.checkbox', { defaultMessage: 'Yes, I have setup trust', })} + labelProps={{ + 'data-test-subj': 'remoteClusterTrustCheckboxLabel', + }} checked={hasSetupTrust} onChange={() => setHasSetupTrust(!hasSetupTrust)} data-test-subj="remoteClusterTrustCheckbox" diff --git a/x-pack/plugins/reporting/public/lib/default_status_context.tsx b/x-pack/plugins/reporting/public/lib/default_status_context.tsx new file mode 100644 index 000000000000..23609e7e0a6a --- /dev/null +++ b/x-pack/plugins/reporting/public/lib/default_status_context.tsx @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ClientConfigType } from '@kbn/reporting-public'; +import React, { createContext, FunctionComponent } from 'react'; +import { IlmPolicyStatusContextProvider } from './ilm_policy_status_context'; + +const PolicyStatusContext = createContext(undefined); + +interface PolicyStatusContextProviderProps { + config: ClientConfigType; +} + +export const PolicyStatusContextProvider: FunctionComponent = ({ + children, + ...props +}) => { + return props.config.statefulSettings.enabled ? ( + {children} + ) : ( + {children} + ); +}; diff --git a/x-pack/plugins/reporting/public/lib/reporting_api_client/hooks.ts b/x-pack/plugins/reporting/public/lib/reporting_api_client/hooks.ts index 5ede6e11ee78..6668e9efe881 100644 --- a/x-pack/plugins/reporting/public/lib/reporting_api_client/hooks.ts +++ b/x-pack/plugins/reporting/public/lib/reporting_api_client/hooks.ts @@ -13,5 +13,6 @@ export const useCheckIlmPolicyStatus = (): UseRequestResponse diff --git a/x-pack/plugins/reporting/public/management/default/report_listing_default.tsx b/x-pack/plugins/reporting/public/management/default/report_listing_default.tsx new file mode 100644 index 000000000000..a2b09ccd3c17 --- /dev/null +++ b/x-pack/plugins/reporting/public/management/default/report_listing_default.tsx @@ -0,0 +1,50 @@ +/* + * 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, { FC } from 'react'; + +import { EuiPageHeader, EuiSpacer } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { ListingPropsInternal } from '..'; +import { ReportListingTable } from '../report_listing_table'; + +/** + * Used in non-stateful (Serverless) + * Does not render controls for features only applicable in Stateful + */ +export const ReportListingDefault: FC = (props) => { + const { apiClient, capabilities, config, navigateToUrl, toasts, urlService, ...listingProps } = + props; + return ( + <> + + } + description={ + + } + /> + + + + ); +}; diff --git a/x-pack/plugins/reporting/public/management/index.ts b/x-pack/plugins/reporting/public/management/index.ts index 4b9074267dd4..bdd6d0a9916b 100644 --- a/x-pack/plugins/reporting/public/management/index.ts +++ b/x-pack/plugins/reporting/public/management/index.ts @@ -8,20 +8,21 @@ import type { ApplicationStart, ToastsSetup } from '@kbn/core/public'; import type { LicensingPluginStart } from '@kbn/licensing-plugin/public'; import type { ClientConfigType } from '@kbn/reporting-public'; -import type { UseIlmPolicyStatusReturn } from '../lib/ilm_policy_status_context'; import type { ReportingAPIClient } from '../lib/reporting_api_client'; import type { SharePluginSetup } from '../shared_imports'; export interface ListingProps { apiClient: ReportingAPIClient; - capabilities: ApplicationStart['capabilities']; license$: LicensingPluginStart['license$']; config: ClientConfigType; redirect: ApplicationStart['navigateToApp']; navigateToUrl: ApplicationStart['navigateToUrl']; toasts: ToastsSetup; urlService: SharePluginSetup['url']; - ilmPolicyContextValue: UseIlmPolicyStatusReturn; } +export type ListingPropsInternal = ListingProps & { + capabilities: ApplicationStart['capabilities']; +}; + export { ReportListing } from './report_listing'; diff --git a/x-pack/plugins/reporting/public/management/mount_management_section.tsx b/x-pack/plugins/reporting/public/management/mount_management_section.tsx index 60cd66d95278..575d9e7c8d7c 100644 --- a/x-pack/plugins/reporting/public/management/mount_management_section.tsx +++ b/x-pack/plugins/reporting/public/management/mount_management_section.tsx @@ -15,10 +15,10 @@ import { ILicense } from '@kbn/licensing-plugin/public'; import { KibanaThemeProvider } from '@kbn/react-kibana-context-theme'; import type { ClientConfigType } from '@kbn/reporting-public'; import { ReportListing } from '.'; -import { IlmPolicyStatusContextProvider } from '../lib/ilm_policy_status_context'; import { InternalApiClientProvider, ReportingAPIClient } from '../lib/reporting_api_client'; import type { ManagementAppMountParams, SharePluginSetup } from '../shared_imports'; import { KibanaContextProvider } from '../shared_imports'; +import { PolicyStatusContextProvider } from '../lib/default_status_context'; export async function mountManagementSection( coreSetup: CoreSetup, @@ -41,8 +41,9 @@ export async function mountManagementSection( }} > - + - + diff --git a/x-pack/plugins/reporting/public/management/report_listing.tsx b/x-pack/plugins/reporting/public/management/report_listing.tsx index 31976dd196a9..024d75b04ae1 100644 --- a/x-pack/plugins/reporting/public/management/report_listing.tsx +++ b/x-pack/plugins/reporting/public/management/report_listing.tsx @@ -5,529 +5,26 @@ * 2.0. */ -import { Component, Fragment, default as React } from 'react'; -import { Subscription } from 'rxjs'; - -import { - EuiBasicTable, - EuiBasicTableColumn, - EuiFlexGroup, - EuiFlexItem, - EuiIconTip, - EuiLink, - EuiLoadingSpinner, - EuiPageHeader, - EuiSpacer, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { ILicense } from '@kbn/licensing-plugin/public'; -import { durationToNumber } from '@kbn/reporting-common'; +import React from 'react'; import { ListingProps as Props } from '.'; -import { REPORT_TABLE_ID, REPORT_TABLE_ROW_ID } from '../../common/constants'; -import { prettyPrintJobType } from '../../common/job_utils'; -import { Poller } from '../../common/poller'; -import { useIlmPolicyStatus } from '../lib/ilm_policy_status_context'; -import { Job } from '../lib/job'; -import { checkLicense } from '../lib/license_check'; import { useInternalApiClient } from '../lib/reporting_api_client'; import { useKibana } from '../shared_imports'; -import { - IlmPolicyLink, - MigrateIlmPolicyCallOut, - ReportDeleteButton, - ReportDiagnostic, - ReportInfoFlyout, - ReportStatusIndicator, -} from './components'; -import { guessAppIconTypeFromObjectType } from './utils'; import './report_listing.scss'; +import { ReportListingStateful } from './stateful/report_listing_stateful'; +import { ReportListingDefault } from './default/report_listing_default'; -type TableColumn = EuiBasicTableColumn; - -interface State { - page: number; - total: number; - jobs: Job[]; - selectedJobs: Job[]; - isLoading: boolean; - showLinks: boolean; - enableLinks: boolean; - badLicenseMessage: string; - selectedJob: undefined | Job; -} - -class ReportListingUi extends Component { - private isInitialJobsFetch: boolean; - private licenseSubscription?: Subscription; - private mounted?: boolean; - private poller?: Poller; - - constructor(props: Props) { - super(props); - - this.state = { - page: 0, - total: 0, - jobs: [], - selectedJobs: [], - isLoading: false, - showLinks: false, - enableLinks: false, - badLicenseMessage: '', - selectedJob: undefined, - }; - - this.isInitialJobsFetch = true; - } - - public render() { - const { - apiClient, - toasts, - ilmPolicyContextValue, - urlService, - navigateToUrl, - capabilities, - config, - } = this.props; - const ilmLocator = urlService.locators.get('ILM_LOCATOR_ID'); - const hasIlmPolicy = ilmPolicyContextValue.status !== 'policy-not-found'; - const showIlmPolicyLink = Boolean(ilmLocator && hasIlmPolicy); - return ( - <> - - } - description={ - - } - /> - - {config.statefulSettings.enabled ? : null} - - -
    {this.renderTable()}
    - - - - {capabilities?.management?.data?.index_lifecycle_management && ( - - {ilmPolicyContextValue.isLoading ? ( - - ) : ( - showIlmPolicyLink && ( - - ) - )} - - )} - - - - - - ); - } - - public componentWillUnmount() { - this.mounted = false; - this.poller?.stop(); - - if (this.licenseSubscription) { - this.licenseSubscription.unsubscribe(); - } - } - - public componentDidMount() { - this.mounted = true; - const { config, license$ } = this.props; - const pollFrequencyInMillis = durationToNumber(config.poll.jobsRefresh.interval); - this.poller = new Poller({ - functionToPoll: () => { - return this.fetchJobs(); - }, - pollFrequencyInMillis, - trailing: false, - continuePollingOnError: true, - pollFrequencyErrorMultiplier: config.poll.jobsRefresh.intervalErrorMultiplier, - }); - this.poller.start(); - this.licenseSubscription = license$.subscribe(this.licenseHandler); - } - - private licenseHandler = (license: ILicense) => { - const { - enableLinks, - showLinks, - message: badLicenseMessage, - } = checkLicense(license.check('reporting', 'basic')); - - this.setState({ - enableLinks, - showLinks, - badLicenseMessage, - }); - }; - - private onSelectionChange = (jobs: Job[]) => { - this.setState((current) => ({ ...current, selectedJobs: jobs })); - }; - - private removeJob = (job: Job) => { - const { jobs } = this.state; - const filtered = jobs.filter((j) => j.id !== job.id); - this.setState((current) => ({ ...current, jobs: filtered })); - }; - - private renderDeleteButton = () => { - const { selectedJobs } = this.state; - if (selectedJobs.length === 0) return undefined; - - const performDelete = async () => { - for (const job of selectedJobs) { - try { - await this.props.apiClient.deleteReport(job.id); - this.removeJob(job); - this.props.toasts.addSuccess( - i18n.translate('xpack.reporting.listing.table.deleteConfim', { - defaultMessage: `The {reportTitle} report was deleted`, - values: { - reportTitle: job.title, - }, - }) - ); - } catch (error) { - this.props.toasts.addDanger( - i18n.translate('xpack.reporting.listing.table.deleteFailedErrorMessage', { - defaultMessage: `The report was not deleted: {error}`, - values: { error }, - }) - ); - throw error; - } - } - }; - - return ( - - ); - }; - - private onTableChange = ({ page }: { page: { index: number } }) => { - const { index: pageIndex } = page; - this.setState(() => ({ page: pageIndex }), this.fetchJobs); - }; - - private fetchJobs = async () => { - // avoid page flicker when poller is updating table - only display loading screen on first load - if (this.isInitialJobsFetch) { - this.setState(() => ({ isLoading: true })); - } - - let jobs: Job[]; - let total: number; - try { - jobs = await this.props.apiClient.list(this.state.page); - total = await this.props.apiClient.total(); - this.isInitialJobsFetch = false; - } catch (fetchError) { - if (!this.licenseAllowsToShowThisPage()) { - this.props.toasts.addDanger(this.state.badLicenseMessage); - this.props.redirect('management'); - return; - } - - if (fetchError.message === 'Failed to fetch') { - this.props.toasts.addDanger( - fetchError.message || - i18n.translate('xpack.reporting.listing.table.requestFailedErrorMessage', { - defaultMessage: 'Request failed', - }) - ); - } - if (this.mounted) { - this.setState(() => ({ isLoading: false, jobs: [], total: 0 })); - } - return; - } - - if (this.mounted) { - this.setState(() => ({ - isLoading: false, - total, - jobs, - })); - } - }; - - private licenseAllowsToShowThisPage = () => { - return this.state.showLinks && this.state.enableLinks; - }; - - /** - * Widths like this are not the best, but the auto-layout does not play well with text in links. We can update - * this with something that works better on all screen sizes. This works for desktop, mobile fallback is provided on a - * per column basis. - */ - private readonly tableColumnWidths = { - type: '5%', - title: '30%', - status: '20%', - createdAt: '25%', - content: '10%', - actions: '10%', - }; - - private renderTable() { - const { tableColumnWidths } = this; - const tableColumns: TableColumn[] = [ - { - field: 'type', - width: tableColumnWidths.type, - name: i18n.translate('xpack.reporting.listing.tableColumns.typeTitle', { - defaultMessage: 'Type', - }), - render: (_type: string, job) => { - return ( -
    - -
    - ); - }, - mobileOptions: { - show: true, - render: (job) => { - return
    {job.objectType}
    ; - }, - }, - }, - { - field: 'title', - name: i18n.translate('xpack.reporting.listing.tableColumns.reportTitle', { - defaultMessage: 'Title', - }), - width: tableColumnWidths.title, - render: (objectTitle: string, job) => { - return ( -
    - this.setState({ selectedJob: job })} - > - {objectTitle || - i18n.translate('xpack.reporting.listing.table.noTitleLabel', { - defaultMessage: 'Untitled', - })} - -
    - ); - }, - mobileOptions: { - header: false, - width: '100%', // This is not recognized by EUI types but has an effect, leaving for now - } as unknown as { header: boolean }, - }, - { - field: 'status', - width: tableColumnWidths.status, - name: i18n.translate('xpack.reporting.listing.tableColumns.statusTitle', { - defaultMessage: 'Status', - }), - render: (_status: string, job) => { - return ( - - - - ); - }, - mobileOptions: { - show: false, - }, - }, - { - field: 'created_at', - width: tableColumnWidths.createdAt, - name: i18n.translate('xpack.reporting.listing.tableColumns.createdAtTitle', { - defaultMessage: 'Created at', - }), - render: (_createdAt: string, job) => ( -
    {job.getCreatedAtDate()}
    - ), - mobileOptions: { - show: false, - }, - }, - { - field: 'content', - width: tableColumnWidths.content, - name: i18n.translate('xpack.reporting.listing.tableColumns.content', { - defaultMessage: 'Content', - }), - render: (_status: string, job) => prettyPrintJobType(job.jobtype), - mobileOptions: { - show: false, - }, - }, - { - name: i18n.translate('xpack.reporting.listing.tableColumns.actionsTitle', { - defaultMessage: 'Actions', - }), - width: tableColumnWidths.actions, - actions: [ - { - isPrimary: true, - 'data-test-subj': 'reportDownloadLink', - type: 'icon', - icon: 'download', - name: i18n.translate('xpack.reporting.listing.table.downloadReportButtonLabel', { - defaultMessage: 'Download report', - }), - description: i18n.translate('xpack.reporting.listing.table.downloadReportDescription', { - defaultMessage: 'Download this report in a new tab.', - }), - onClick: (job) => this.props.apiClient.downloadReport(job.id), - enabled: (job) => job.isDownloadReady, - }, - { - name: i18n.translate( - 'xpack.reporting.listing.table.viewReportingInfoActionButtonLabel', - { - defaultMessage: 'View report info', - } - ), - description: i18n.translate( - 'xpack.reporting.listing.table.viewReportingInfoActionButtonDescription', - { - defaultMessage: 'View additional information about this report.', - } - ), - type: 'icon', - icon: 'iInCircle', - onClick: (job) => this.setState({ selectedJob: job }), - }, - { - name: i18n.translate('xpack.reporting.listing.table.openInKibanaAppLabel', { - defaultMessage: 'Open in Kibana', - }), - 'data-test-subj': 'reportOpenInKibanaApp', - description: i18n.translate( - 'xpack.reporting.listing.table.openInKibanaAppDescription', - { - defaultMessage: 'Open the Kibana app where this report was generated.', - } - ), - available: (job) => job.canLinkToKibanaApp, - type: 'icon', - icon: 'popout', - onClick: (job) => { - const href = this.props.apiClient.getKibanaAppHref(job); - window.open(href, '_blank'); - window.focus(); - }, - }, - ], - }, - ]; - - const pagination = { - pageIndex: this.state.page, - pageSize: 10, - totalItemCount: this.state.total, - showPerPageOptions: false, - }; - - const selection = { - itemId: 'id', - onSelectionChange: this.onSelectionChange, - }; - - return ( - - {this.state.selectedJobs.length > 0 && ( - - - {this.renderDeleteButton()} - - - - )} - ({ 'data-test-subj': REPORT_TABLE_ROW_ID })} - /> - {!!this.state.selectedJob && ( - this.setState({ selectedJob: undefined })} - job={this.state.selectedJob} - /> - )} - - ); - } -} - -export const ReportListing = ( - props: Omit< - Props, - 'ilmPolicyContextValue' | 'intl' | 'apiClient' | 'capabilities' | 'configAllowsImages' - > -) => { - const ilmPolicyStatusValue = useIlmPolicyStatus(); +export const ReportListing = (props: Props) => { const { apiClient } = useInternalApiClient(); const { services: { application: { capabilities }, }, } = useKibana(); - return ( - + return props.config.statefulSettings.enabled ? ( + + ) : ( + ); }; diff --git a/x-pack/plugins/reporting/public/management/report_listing_table.tsx b/x-pack/plugins/reporting/public/management/report_listing_table.tsx new file mode 100644 index 000000000000..61b9e7d54192 --- /dev/null +++ b/x-pack/plugins/reporting/public/management/report_listing_table.tsx @@ -0,0 +1,440 @@ +/* + * 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 { Component, Fragment, default as React } from 'react'; +import { Subscription } from 'rxjs'; + +import { + EuiBasicTable, + EuiBasicTableColumn, + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiLink, + EuiSpacer, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ILicense } from '@kbn/licensing-plugin/public'; +import { durationToNumber } from '@kbn/reporting-common'; + +import { REPORT_TABLE_ID, REPORT_TABLE_ROW_ID } from '../../common/constants'; +import { prettyPrintJobType } from '../../common/job_utils'; +import { Poller } from '../../common/poller'; +import { Job } from '../lib/job'; +import { checkLicense } from '../lib/license_check'; +import { ReportDeleteButton, ReportInfoFlyout, ReportStatusIndicator } from './components'; +import { guessAppIconTypeFromObjectType } from './utils'; +import { ListingPropsInternal } from '.'; + +type TableColumn = EuiBasicTableColumn; + +interface State { + page: number; + total: number; + jobs: Job[]; + selectedJobs: Job[]; + isLoading: boolean; + showLinks: boolean; + enableLinks: boolean; + badLicenseMessage: string; + selectedJob: undefined | Job; +} + +export class ReportListingTable extends Component { + private isInitialJobsFetch: boolean; + private licenseSubscription?: Subscription; + private mounted?: boolean; + private poller?: Poller; + + constructor(props: ListingPropsInternal) { + super(props); + + this.state = { + page: 0, + total: 0, + jobs: [], + selectedJobs: [], + isLoading: false, + showLinks: false, + enableLinks: false, + badLicenseMessage: '', + selectedJob: undefined, + }; + + this.isInitialJobsFetch = true; + } + + public componentWillUnmount() { + this.mounted = false; + this.poller?.stop(); + + if (this.licenseSubscription) { + this.licenseSubscription.unsubscribe(); + } + } + + public componentDidMount() { + this.mounted = true; + const { config, license$ } = this.props; + const pollFrequencyInMillis = durationToNumber(config.poll.jobsRefresh.interval); + this.poller = new Poller({ + functionToPoll: () => { + return this.fetchJobs(); + }, + pollFrequencyInMillis, + trailing: false, + continuePollingOnError: true, + pollFrequencyErrorMultiplier: config.poll.jobsRefresh.intervalErrorMultiplier, + }); + this.poller.start(); + this.licenseSubscription = license$.subscribe(this.licenseHandler); + } + + private licenseHandler = (license: ILicense) => { + const { + enableLinks, + showLinks, + message: badLicenseMessage, + } = checkLicense(license.check('reporting', 'basic')); + + this.setState({ + enableLinks, + showLinks, + badLicenseMessage, + }); + }; + + private onSelectionChange = (jobs: Job[]) => { + this.setState((current) => ({ ...current, selectedJobs: jobs })); + }; + + private removeJob = (job: Job) => { + const { jobs } = this.state; + const filtered = jobs.filter((j) => j.id !== job.id); + this.setState((current) => ({ ...current, jobs: filtered })); + }; + + private renderDeleteButton = () => { + const { selectedJobs } = this.state; + if (selectedJobs.length === 0) return undefined; + + const performDelete = async () => { + for (const job of selectedJobs) { + try { + await this.props.apiClient.deleteReport(job.id); + this.removeJob(job); + this.props.toasts.addSuccess( + i18n.translate('xpack.reporting.listing.table.deleteConfim', { + defaultMessage: `The {reportTitle} report was deleted`, + values: { + reportTitle: job.title, + }, + }) + ); + } catch (error) { + this.props.toasts.addDanger( + i18n.translate('xpack.reporting.listing.table.deleteFailedErrorMessage', { + defaultMessage: `The report was not deleted: {error}`, + values: { error }, + }) + ); + throw error; + } + } + }; + + return ( + + ); + }; + + private onTableChange = ({ page }: { page: { index: number } }) => { + const { index: pageIndex } = page; + this.setState(() => ({ page: pageIndex }), this.fetchJobs); + }; + + private fetchJobs = async () => { + // avoid page flicker when poller is updating table - only display loading screen on first load + if (this.isInitialJobsFetch) { + this.setState(() => ({ isLoading: true })); + } + + let jobs: Job[]; + let total: number; + try { + jobs = await this.props.apiClient.list(this.state.page); + total = await this.props.apiClient.total(); + this.isInitialJobsFetch = false; + } catch (fetchError) { + if (!this.licenseAllowsToShowThisPage()) { + this.props.toasts.addDanger(this.state.badLicenseMessage); + this.props.redirect('management'); + return; + } + + if (fetchError.message === 'Failed to fetch') { + this.props.toasts.addDanger( + fetchError.message || + i18n.translate('xpack.reporting.listing.table.requestFailedErrorMessage', { + defaultMessage: 'Request failed', + }) + ); + } + if (this.mounted) { + this.setState(() => ({ isLoading: false, jobs: [], total: 0 })); + } + return; + } + + if (this.mounted) { + this.setState(() => ({ + isLoading: false, + total, + jobs, + })); + } + }; + + private licenseAllowsToShowThisPage = () => { + return this.state.showLinks && this.state.enableLinks; + }; + + /** + * Widths like this are not the best, but the auto-layout does not play well with text in links. We can update + * this with something that works better on all screen sizes. This works for desktop, mobile fallback is provided on a + * per column basis. + */ + private readonly tableColumnWidths = { + type: '5%', + title: '30%', + status: '20%', + createdAt: '25%', + content: '10%', + actions: '10%', + }; + + public render() { + const { tableColumnWidths } = this; + const tableColumns: TableColumn[] = [ + { + field: 'type', + width: tableColumnWidths.type, + name: i18n.translate('xpack.reporting.listing.tableColumns.typeTitle', { + defaultMessage: 'Type', + }), + render: (_type: string, job) => { + return ( +
    + +
    + ); + }, + mobileOptions: { + show: true, + render: (job) => { + return
    {job.objectType}
    ; + }, + }, + }, + { + field: 'title', + name: i18n.translate('xpack.reporting.listing.tableColumns.reportTitle', { + defaultMessage: 'Title', + }), + width: tableColumnWidths.title, + render: (objectTitle: string, job) => { + return ( +
    + this.setState({ selectedJob: job })} + > + {objectTitle || + i18n.translate('xpack.reporting.listing.table.noTitleLabel', { + defaultMessage: 'Untitled', + })} + +
    + ); + }, + mobileOptions: { + header: false, + width: '100%', // This is not recognized by EUI types but has an effect, leaving for now + } as unknown as { header: boolean }, + }, + { + field: 'status', + width: tableColumnWidths.status, + name: i18n.translate('xpack.reporting.listing.tableColumns.statusTitle', { + defaultMessage: 'Status', + }), + render: (_status: string, job) => { + return ( + + + + ); + }, + mobileOptions: { + show: false, + }, + }, + { + field: 'created_at', + width: tableColumnWidths.createdAt, + name: i18n.translate('xpack.reporting.listing.tableColumns.createdAtTitle', { + defaultMessage: 'Created at', + }), + render: (_createdAt: string, job) => ( +
    {job.getCreatedAtDate()}
    + ), + mobileOptions: { + show: false, + }, + }, + { + field: 'content', + width: tableColumnWidths.content, + name: i18n.translate('xpack.reporting.listing.tableColumns.content', { + defaultMessage: 'Content', + }), + render: (_status: string, job) => prettyPrintJobType(job.jobtype), + mobileOptions: { + show: false, + }, + }, + { + name: i18n.translate('xpack.reporting.listing.tableColumns.actionsTitle', { + defaultMessage: 'Actions', + }), + width: tableColumnWidths.actions, + actions: [ + { + isPrimary: true, + 'data-test-subj': 'reportDownloadLink', + type: 'icon', + icon: 'download', + name: i18n.translate('xpack.reporting.listing.table.downloadReportButtonLabel', { + defaultMessage: 'Download report', + }), + description: i18n.translate('xpack.reporting.listing.table.downloadReportDescription', { + defaultMessage: 'Download this report in a new tab.', + }), + onClick: (job) => this.props.apiClient.downloadReport(job.id), + enabled: (job) => job.isDownloadReady, + }, + { + name: i18n.translate( + 'xpack.reporting.listing.table.viewReportingInfoActionButtonLabel', + { + defaultMessage: 'View report info', + } + ), + description: i18n.translate( + 'xpack.reporting.listing.table.viewReportingInfoActionButtonDescription', + { + defaultMessage: 'View additional information about this report.', + } + ), + type: 'icon', + icon: 'iInCircle', + onClick: (job) => this.setState({ selectedJob: job }), + }, + { + name: i18n.translate('xpack.reporting.listing.table.openInKibanaAppLabel', { + defaultMessage: 'Open in Kibana', + }), + 'data-test-subj': 'reportOpenInKibanaApp', + description: i18n.translate( + 'xpack.reporting.listing.table.openInKibanaAppDescription', + { + defaultMessage: 'Open the Kibana app where this report was generated.', + } + ), + available: (job) => job.canLinkToKibanaApp, + type: 'icon', + icon: 'popout', + onClick: (job) => { + const href = this.props.apiClient.getKibanaAppHref(job); + window.open(href, '_blank'); + window.focus(); + }, + }, + ], + }, + ]; + + const pagination = { + pageIndex: this.state.page, + pageSize: 10, + totalItemCount: this.state.total, + showPerPageOptions: false, + }; + + const selection = { + itemId: 'id', + onSelectionChange: this.onSelectionChange, + }; + + return ( + + {this.state.selectedJobs.length > 0 && ( + + + {this.renderDeleteButton()} + + + + )} + ({ 'data-test-subj': REPORT_TABLE_ROW_ID })} + /> + {!!this.state.selectedJob && ( + this.setState({ selectedJob: undefined })} + job={this.state.selectedJob} + /> + )} + + ); + } +} diff --git a/x-pack/plugins/reporting/public/management/stateful/report_listing_stateful.tsx b/x-pack/plugins/reporting/public/management/stateful/report_listing_stateful.tsx new file mode 100644 index 000000000000..3e7a3c8cb10f --- /dev/null +++ b/x-pack/plugins/reporting/public/management/stateful/report_listing_stateful.tsx @@ -0,0 +1,87 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; + +import { + EuiFlexGroup, + EuiFlexItem, + EuiLoadingSpinner, + EuiPageHeader, + EuiSpacer, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import { ListingPropsInternal } from '..'; +import { useIlmPolicyStatus } from '../../lib/ilm_policy_status_context'; +import { IlmPolicyLink, MigrateIlmPolicyCallOut, ReportDiagnostic } from '../components'; +import { ReportListingTable } from '../report_listing_table'; + +/** + * Used in Stateful deployments only + * Renders controls for ILM and Screenshotting Diagnostics which are only applicable in Stateful + */ +export const ReportListingStateful: FC = (props) => { + const { apiClient, capabilities, config, navigateToUrl, toasts, urlService, ...listingProps } = + props; + const ilmLocator = urlService.locators.get('ILM_LOCATOR_ID'); + const ilmPolicyContextValue = useIlmPolicyStatus(); + const hasIlmPolicy = ilmPolicyContextValue?.status !== 'policy-not-found'; + const showIlmPolicyLink = Boolean(ilmLocator && hasIlmPolicy); + return ( + <> + + } + description={ + + } + /> + + + + + + + + + + {capabilities?.management?.data?.index_lifecycle_management && ( + + {ilmPolicyContextValue?.isLoading ? ( + + ) : ( + showIlmPolicyLink && ( + + ) + )} + + )} + + + + + + ); +}; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index 47eeb6e46c40..f395ddb4b75f 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -22,6 +22,7 @@ import { ALERT_STATUS_ACTIVE, ALERT_CASE_IDS, MAX_CASES_PER_ALERT, + AlertConsumers, } from '@kbn/rule-data-utils'; import { @@ -80,6 +81,7 @@ export interface ConstructorOptions { esClient: ElasticsearchClient; ruleDataService: IRuleDataService; getRuleType: RuleTypeRegistry['get']; + getRuleList: RuleTypeRegistry['list']; getAlertIndicesAlias: AlertingStart['getAlertIndicesAlias']; } @@ -153,6 +155,7 @@ export class AlertsClient { private readonly spaceId: string | undefined; private readonly ruleDataService: IRuleDataService; private readonly getRuleType: RuleTypeRegistry['get']; + private readonly getRuleList: RuleTypeRegistry['list']; private getAlertIndicesAlias!: AlertingStart['getAlertIndicesAlias']; constructor(options: ConstructorOptions) { @@ -165,6 +168,7 @@ export class AlertsClient { this.spaceId = this.authorization.getSpaceId(); this.ruleDataService = options.ruleDataService; this.getRuleType = options.getRuleType; + this.getRuleList = options.getRuleList; this.getAlertIndicesAlias = options.getAlertIndicesAlias; } @@ -1076,19 +1080,31 @@ export class AlertsClient { } public async getBrowserFields({ + featureIds, indices, metaFields, allowNoIndex, }: { + featureIds: string[]; indices: string[]; metaFields: string[]; allowNoIndex: boolean; }): Promise<{ browserFields: BrowserFields; fields: FieldDescriptor[] }> { const indexPatternsFetcherAsInternalUser = new IndexPatternsFetcher(this.esClient); + const ruleTypeList = this.getRuleList(); + const fieldsForAAD = new Set(); + for (const rule of ruleTypeList) { + if (featureIds.includes(rule.producer) && rule.hasFieldsForAAD) { + (rule.fieldsForAAD ?? []).forEach((f) => { + fieldsForAAD.add(f); + }); + } + } const { fields } = await indexPatternsFetcherAsInternalUser.getFieldsForWildcard({ pattern: indices, metaFields, fieldCapsOptions: { allow_no_indices: allowNoIndex }, + fields: [...fieldsForAAD, 'kibana.*'], }); return { @@ -1099,11 +1115,13 @@ export class AlertsClient { public async getAADFields({ ruleTypeId }: { ruleTypeId: string }) { const { producer, fieldsForAAD = [] } = this.getRuleType(ruleTypeId); + if (producer === AlertConsumers.SIEM) { + throw Boom.badRequest(`Security solution rule type is not supported`); + } const indices = await this.getAuthorizedAlertsIndices([producer]); - const o11yIndices = indices?.filter((index) => index.startsWith('.alerts-observability')) ?? []; const indexPatternsFetcherAsInternalUser = new IndexPatternsFetcher(this.esClient); - const { fields } = await indexPatternsFetcherAsInternalUser.getFieldsForWildcard({ - pattern: o11yIndices, + const { fields = [] } = await indexPatternsFetcherAsInternalUser.getFieldsForWildcard({ + pattern: indices ?? [], metaFields: ['_id', '_index'], fieldCapsOptions: { allow_no_indices: true }, fields: [...fieldsForAAD, 'kibana.*'], diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.test.ts index 43966d120700..367ead5744d5 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.test.ts @@ -26,6 +26,7 @@ const alertsClientFactoryParams: AlertsClientFactoryProps = { esClient: {} as ElasticsearchClient, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; @@ -53,6 +54,7 @@ describe('AlertsClientFactory', () => { auditLogger, esClient: {}, ruleDataService: alertsClientFactoryParams.ruleDataService, + getRuleList: alertsClientFactoryParams.getRuleList, getRuleType: alertsClientFactoryParams.getRuleType, getAlertIndicesAlias: alertsClientFactoryParams.getAlertIndicesAlias, }); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.ts index de0afb5a0b22..934074cc4a2e 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client_factory.ts @@ -23,6 +23,7 @@ export interface AlertsClientFactoryProps { securityPluginSetup: SecurityPluginSetup | undefined; ruleDataService: IRuleDataService | null; getRuleType: RuleTypeRegistry['get']; + getRuleList: RuleTypeRegistry['list']; getAlertIndicesAlias: AlertingStart['getAlertIndicesAlias']; } @@ -36,6 +37,7 @@ export class AlertsClientFactory { private securityPluginSetup!: SecurityPluginSetup | undefined; private ruleDataService!: IRuleDataService | null; private getRuleType!: RuleTypeRegistry['get']; + private getRuleList!: RuleTypeRegistry['list']; private getAlertIndicesAlias!: AlertingStart['getAlertIndicesAlias']; public initialize(options: AlertsClientFactoryProps) { @@ -53,6 +55,7 @@ export class AlertsClientFactory { this.securityPluginSetup = options.securityPluginSetup; this.ruleDataService = options.ruleDataService; this.getRuleType = options.getRuleType; + this.getRuleList = options.getRuleList; this.getAlertIndicesAlias = options.getAlertIndicesAlias; } @@ -66,6 +69,7 @@ export class AlertsClientFactory { esClient: this.esClient, ruleDataService: this.ruleDataService!, getRuleType: this.getRuleType, + getRuleList: this.getRuleList, getAlertIndicesAlias: this.getAlertIndicesAlias, }); } diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts index 4229ae23793f..28cd76ca6dff 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update.test.ts @@ -31,6 +31,7 @@ const alertsClientParams: jest.Mocked = { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update_cases.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update_cases.test.ts index 4047a3ecadd2..544fab479f9d 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update_cases.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/bulk_update_cases.test.ts @@ -37,6 +37,7 @@ describe('bulkUpdateCases', () => { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts index 37ad46a523a7..8ccae88dd83c 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/find_alerts.test.ts @@ -30,6 +30,7 @@ const alertsClientParams: jest.Mocked = { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts index fb1e0eef432e..4185fb7e83eb 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get.test.ts @@ -31,6 +31,7 @@ const alertsClientParams: jest.Mocked = { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_aad_fields.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_aad_fields.test.ts new file mode 100644 index 000000000000..777b3d3e2674 --- /dev/null +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/get_aad_fields.test.ts @@ -0,0 +1,50 @@ +/* + * 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 { AlertConsumers } from '@kbn/rule-data-utils'; +import { AlertsClient, ConstructorOptions } from '../alerts_client'; +import { loggingSystemMock } from '@kbn/core/server/mocks'; +import { elasticsearchClientMock } from '@kbn/core-elasticsearch-client-server-mocks'; +import { alertingAuthorizationMock } from '@kbn/alerting-plugin/server/authorization/alerting_authorization.mock'; +import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; +import { ruleDataServiceMock } from '../../rule_data_plugin_service/rule_data_plugin_service.mock'; + +const alertingAuthMock = alertingAuthorizationMock.create(); +const esClientMock = elasticsearchClientMock.createElasticsearchClient(); +const auditLogger = auditLoggerMock.create(); +const getRuleTypeMock = jest.fn(); +const alertsClientParams: jest.Mocked = { + logger: loggingSystemMock.create().get(), + authorization: alertingAuthMock, + esClient: esClientMock, + auditLogger, + ruleDataService: ruleDataServiceMock.create(), + getRuleType: getRuleTypeMock, + getRuleList: jest.fn(), + getAlertIndicesAlias: jest.fn(), +}; + +const DEFAULT_SPACE = 'test_default_space_id'; + +beforeEach(() => { + jest.resetAllMocks(); + alertingAuthMock.getSpaceId.mockImplementation(() => DEFAULT_SPACE); +}); + +describe('getAADFields()', () => { + test('should throw an error when a rule type belong to security solution', async () => { + getRuleTypeMock.mockImplementation(() => ({ + producer: AlertConsumers.SIEM, + fieldsForAAD: [], + })); + const alertsClient = new AlertsClient(alertsClientParams); + + await expect( + alertsClient.getAADFields({ ruleTypeId: 'security-type' }) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"Security solution rule type is not supported"`); + }); +}); diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/remove_cases_from_alerts.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/remove_cases_from_alerts.test.ts index 2611200afd85..317de5d52e8e 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/remove_cases_from_alerts.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/remove_cases_from_alerts.test.ts @@ -32,6 +32,7 @@ describe('remove cases from alerts', () => { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; @@ -90,6 +91,7 @@ describe('remove cases from alerts', () => { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts index bca5e7d967f3..bd6a1b2695cd 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/tests/update.test.ts @@ -30,6 +30,7 @@ const alertsClientParams: jest.Mocked = { auditLogger, ruleDataService: ruleDataServiceMock.create(), getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: jest.fn(), }; diff --git a/x-pack/plugins/rule_registry/server/plugin.ts b/x-pack/plugins/rule_registry/server/plugin.ts index 6fba837a10c1..8cb6df23ae76 100644 --- a/x-pack/plugins/rule_registry/server/plugin.ts +++ b/x-pack/plugins/rule_registry/server/plugin.ts @@ -166,6 +166,7 @@ export class RuleRegistryPlugin securityPluginSetup: security, ruleDataService, getRuleType: plugins.alerting.getType, + getRuleList: plugins.alerting.listTypes, getAlertIndicesAlias: plugins.alerting.getAlertIndicesAlias, }); diff --git a/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_feature_id.ts b/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_feature_id.ts index 259ca0347874..995f992e0b80 100644 --- a/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_feature_id.ts +++ b/x-pack/plugins/rule_registry/server/routes/get_browser_fields_by_feature_id.ts @@ -53,6 +53,7 @@ export const getBrowserFieldsByFeatureId = (router: IRouter = ({ user }) labelAppend={} fullWidth > - + = ({ user }) labelAppend={} fullWidth > - + ); @@ -189,6 +189,7 @@ const UserSettingsEditor: FunctionComponent = ({ = ({ user, data }) {formChanges.count > 0 ? ( - + ) : null} @@ -974,6 +979,7 @@ export const SaveChangesBottomBar: FunctionComponent = () => { 0 && !formik.isValid} color="success" diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index a7460bcd7034..75eda07fa185 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -429,6 +429,7 @@ export const RULES_TABLE_MAX_PAGE_SIZE = 100; */ export const NEW_FEATURES_TOUR_STORAGE_KEYS = { RULE_MANAGEMENT_PAGE: 'securitySolution.rulesManagementPage.newFeaturesTour.v8.11', + TIMELINES: 'securitySolution.security.timelineFlyoutHeader.saveTimelineTour', }; export const RULE_DETAILS_EXECUTION_LOG_TABLE_SHOW_METRIC_COLUMNS_STORAGE_KEY = @@ -449,8 +450,8 @@ export const RISKY_HOSTS_DOC_LINK = 'https://www.elastic.co/guide/en/security/current/host-risk-score.html'; export const RISKY_USERS_DOC_LINK = 'https://www.elastic.co/guide/en/security/current/user-risk-score.html'; -export const DETECTION_ENTITY_DASHBOARD = - 'https://www.elastic.co/guide/en/security/current/detection-entity-dashboard.html'; +export const RISKY_ENTITY_SCORE_DOC_LINK = + 'https://www.elastic.co/guide/en/security/current/advanced-entity-analytics-overview.html#entity-risk-scoring'; export const MAX_NUMBER_OF_NEW_TERMS_FIELDS = 3; diff --git a/x-pack/plugins/security_solution/common/experimental_features.ts b/x-pack/plugins/security_solution/common/experimental_features.ts index b080981713de..e2756d1955e3 100644 --- a/x-pack/plugins/security_solution/common/experimental_features.ts +++ b/x-pack/plugins/security_solution/common/experimental_features.ts @@ -108,12 +108,6 @@ export const allowedExperimentalValues = Object.freeze({ * Enables Protection Updates tab in the Endpoint Policy Details page */ protectionUpdatesEnabled: true, - - /** - * Disables the timeline save tour. - * This flag is used to disable the tour in cypress tests. - */ - disableTimelineSaveTour: false, }); type ExperimentalConfigKeys = Array; diff --git a/x-pack/plugins/security_solution/public/app/index.tsx b/x-pack/plugins/security_solution/public/app/index.tsx index 6f0fc3eb8d01..3053590ae3d9 100644 --- a/x-pack/plugins/security_solution/public/app/index.tsx +++ b/x-pack/plugins/security_solution/public/app/index.tsx @@ -7,7 +7,6 @@ import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; -import { SubscriptionTrackingProvider } from '@kbn/subscription-tracking'; import { SecurityApp } from './app'; import type { RenderAppProps } from './types'; import { AppRoutes } from './app_routes'; @@ -21,7 +20,6 @@ export const renderApp = ({ usageCollection, subPluginRoutes, theme$, - subscriptionTrackingServices, }: RenderAppProps): (() => void) => { const ApplicationUsageTrackingProvider = usageCollection?.components.ApplicationUsageTrackingProvider ?? React.Fragment; @@ -34,12 +32,7 @@ export const renderApp = ({ theme$={theme$} > - - - + , element diff --git a/x-pack/plugins/security_solution/public/app/types.ts b/x-pack/plugins/security_solution/public/app/types.ts index 66bab19c945f..578a4800f7f6 100644 --- a/x-pack/plugins/security_solution/public/app/types.ts +++ b/x-pack/plugins/security_solution/public/app/types.ts @@ -19,7 +19,6 @@ import type { RouteProps } from 'react-router-dom'; import type { AppMountParameters } from '@kbn/core/public'; import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public'; import type { TableState } from '@kbn/securitysolution-data-table'; -import type { Services as SubscriptionTrackingServices } from '@kbn/subscription-tracking'; import type { ExploreReducer, ExploreState } from '../explore'; import type { StartServices } from '../types'; @@ -30,7 +29,6 @@ export interface RenderAppProps extends AppMountParameters { services: StartServices; store: Store; subPluginRoutes: RouteProps[]; - subscriptionTrackingServices: SubscriptionTrackingServices; usageCollection?: UsageCollectionSetup; } diff --git a/x-pack/plugins/security_solution/public/assistant/get_comments/index.tsx b/x-pack/plugins/security_solution/public/assistant/get_comments/index.tsx index 3b778013a42d..d8cfc46ec5a2 100644 --- a/x-pack/plugins/security_solution/public/assistant/get_comments/index.tsx +++ b/x-pack/plugins/security_solution/public/assistant/get_comments/index.tsx @@ -66,6 +66,8 @@ export const getComments = ({ regenerateMessage(currentConversation.id); }; + const connectorTypeTitle = currentConversation.apiConfig.connectorTypeTitle ?? ''; + const extraLoadingComment = isFetchingResponse ? [ { @@ -75,6 +77,7 @@ export const getComments = ({ children: ( ; regenerateMessage: () => void; transformMessage: (message: string) => ContentMessage; @@ -29,6 +30,7 @@ interface Props { export const StreamComment = ({ amendMessage, content, + connectorTypeTitle, index, isError = false, isFetching = false, @@ -40,6 +42,7 @@ export const StreamComment = ({ const { error, isLoading, isStreaming, pendingMessage, setComplete } = useStream({ amendMessage, content, + connectorTypeTitle, reader, isError, }); diff --git a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.test.ts b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.test.ts index 764db1b3990a..54a5684d2044 100644 --- a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.test.ts +++ b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.test.ts @@ -9,6 +9,8 @@ import { API_ERROR } from '../translations'; import type { PromptObservableState } from './types'; import { Subject } from 'rxjs'; +import { EventStreamCodec } from '@smithy/eventstream-codec'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; describe('getStreamObservable', () => { const mockReader = { read: jest.fn(), @@ -22,29 +24,102 @@ describe('getStreamObservable', () => { beforeEach(() => { jest.clearAllMocks(); }); + it('should emit loading state and chunks for Bedrock', (done) => { + const completeSubject = new Subject(); + const expectedStates: PromptObservableState[] = [ + { chunks: [], loading: true }, + { + // when i log the actual emit, chunks equal to message.split(''); test is wrong + chunks: ['My', ' new', ' message'], + message: 'My', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new message', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new message', + loading: false, + }, + ]; - it('should emit loading state and chunks', (done) => { + mockReader.read + .mockResolvedValueOnce({ + done: false, + value: encodeBedrockResponse('My'), + }) + .mockResolvedValueOnce({ + done: false, + value: encodeBedrockResponse(' new'), + }) + .mockResolvedValueOnce({ + done: false, + value: encodeBedrockResponse(' message'), + }) + .mockResolvedValue({ + done: true, + }); + + const source = getStreamObservable({ + connectorTypeTitle: 'Amazon Bedrock', + isError: false, + reader: typedReader, + setLoading, + }); + const emittedStates: PromptObservableState[] = []; + + source.subscribe({ + next: (state) => { + return emittedStates.push(state); + }, + complete: () => { + expect(emittedStates).toEqual(expectedStates); + done(); + + completeSubject.subscribe({ + next: () => { + expect(setLoading).toHaveBeenCalledWith(false); + expect(typedReader.cancel).toHaveBeenCalled(); + done(); + }, + }); + }, + error: (err) => done(err), + }); + }); + it('should emit loading state and chunks for OpenAI', (done) => { + const chunk1 = `data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"My"}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" new"}}]}`; + const chunk2 = `\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" message"}}]}\ndata: [DONE]`; const completeSubject = new Subject(); const expectedStates: PromptObservableState[] = [ { chunks: [], loading: true }, { - chunks: ['one chunk ', 'another chunk', ''], - message: 'one chunk ', + // when i log the actual emit, chunks equal to message.split(''); test is wrong + chunks: ['My', ' new', ' message'], + message: 'My', loading: true, }, { - chunks: ['one chunk ', 'another chunk', ''], - message: 'one chunk another chunk', + chunks: ['My', ' new', ' message'], + message: 'My new', loading: true, }, { - chunks: ['one chunk ', 'another chunk', ''], - message: 'one chunk another chunk', + chunks: ['My', ' new', ' message'], + message: 'My new message', loading: true, }, { - chunks: ['one chunk ', 'another chunk', ''], - message: 'one chunk another chunk', + chunks: ['My', ' new', ' message'], + message: 'My new message', loading: false, }, ]; @@ -52,11 +127,11 @@ describe('getStreamObservable', () => { mockReader.read .mockResolvedValueOnce({ done: false, - value: new Uint8Array(new TextEncoder().encode(`one chunk `)), + value: new Uint8Array(new TextEncoder().encode(chunk1)), }) .mockResolvedValueOnce({ done: false, - value: new Uint8Array(new TextEncoder().encode(`another chunk`)), + value: new Uint8Array(new TextEncoder().encode(chunk2)), }) .mockResolvedValueOnce({ done: false, @@ -66,11 +141,91 @@ describe('getStreamObservable', () => { done: true, }); - const source = getStreamObservable(typedReader, setLoading, false); + const source = getStreamObservable({ + connectorTypeTitle: 'OpenAI', + isError: false, + reader: typedReader, + setLoading, + }); const emittedStates: PromptObservableState[] = []; source.subscribe({ - next: (state) => emittedStates.push(state), + next: (state) => { + return emittedStates.push(state); + }, + complete: () => { + expect(emittedStates).toEqual(expectedStates); + done(); + + completeSubject.subscribe({ + next: () => { + expect(setLoading).toHaveBeenCalledWith(false); + expect(typedReader.cancel).toHaveBeenCalled(); + done(); + }, + }); + }, + error: (err) => done(err), + }); + }); + it('should emit loading state and chunks for partial response OpenAI', (done) => { + const chunk1 = `data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"My"}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" new"`; + const chunk2 = `}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" message"}}]}\ndata: [DONE]`; + const completeSubject = new Subject(); + const expectedStates: PromptObservableState[] = [ + { chunks: [], loading: true }, + { + // when i log the actual emit, chunks equal to message.split(''); test is wrong + chunks: ['My', ' new', ' message'], + message: 'My', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new message', + loading: true, + }, + { + chunks: ['My', ' new', ' message'], + message: 'My new message', + loading: false, + }, + ]; + + mockReader.read + .mockResolvedValueOnce({ + done: false, + value: new Uint8Array(new TextEncoder().encode(chunk1)), + }) + .mockResolvedValueOnce({ + done: false, + value: new Uint8Array(new TextEncoder().encode(chunk2)), + }) + .mockResolvedValueOnce({ + done: false, + value: new Uint8Array(new TextEncoder().encode('')), + }) + .mockResolvedValue({ + done: true, + }); + + const source = getStreamObservable({ + connectorTypeTitle: 'OpenAI', + isError: false, + reader: typedReader, + setLoading, + }); + const emittedStates: PromptObservableState[] = []; + + source.subscribe({ + next: (state) => { + return emittedStates.push(state); + }, complete: () => { expect(emittedStates).toEqual(expectedStates); done(); @@ -112,7 +267,12 @@ describe('getStreamObservable', () => { done: true, }); - const source = getStreamObservable(typedReader, setLoading, true); + const source = getStreamObservable({ + connectorTypeTitle: 'OpenAI', + isError: true, + reader: typedReader, + setLoading, + }); const emittedStates: PromptObservableState[] = []; source.subscribe({ @@ -138,7 +298,12 @@ describe('getStreamObservable', () => { const error = new Error('Test Error'); // Simulate an error mockReader.read.mockRejectedValue(error); - const source = getStreamObservable(typedReader, setLoading, false); + const source = getStreamObservable({ + connectorTypeTitle: 'OpenAI', + isError: false, + reader: typedReader, + setLoading, + }); source.subscribe({ next: (state) => {}, @@ -157,3 +322,16 @@ describe('getStreamObservable', () => { }); }); }); + +function encodeBedrockResponse(completion: string) { + return new EventStreamCodec(toUtf8, fromUtf8).encode({ + headers: {}, + body: Uint8Array.from( + Buffer.from( + JSON.stringify({ + bytes: Buffer.from(JSON.stringify({ completion })).toString('base64'), + }) + ) + ), + }); +} diff --git a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.ts b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.ts index b30be69b82ca..ce7a38811f22 100644 --- a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.ts +++ b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/stream_observable.ts @@ -7,10 +7,18 @@ import { concatMap, delay, finalize, Observable, of, scan, timestamp } from 'rxjs'; import type { Dispatch, SetStateAction } from 'react'; -import { API_ERROR } from '../translations'; +import { EventStreamCodec } from '@smithy/eventstream-codec'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; import type { PromptObservableState } from './types'; +import { API_ERROR } from '../translations'; const MIN_DELAY = 35; +interface StreamObservable { + connectorTypeTitle: string; + reader: ReadableStreamDefaultReader; + setLoading: Dispatch>; + isError: boolean; +} /** * Returns an Observable that reads data from a ReadableStream and emits values representing the state of the data processing. * @@ -19,52 +27,155 @@ const MIN_DELAY = 35; * @param isError - indicates whether the reader response is an error message or not * @returns {Observable} An Observable that emits PromptObservableState */ -export const getStreamObservable = ( - reader: ReadableStreamDefaultReader, - setLoading: Dispatch>, - isError: boolean -): Observable => +export const getStreamObservable = ({ + connectorTypeTitle, + isError, + reader, + setLoading, +}: StreamObservable): Observable => new Observable((observer) => { observer.next({ chunks: [], loading: true }); const decoder = new TextDecoder(); const chunks: string[] = []; - function read() { + // Initialize an empty string to store the OpenAI buffer. + let openAIBuffer: string = ''; + + // Initialize an empty Uint8Array to store the Bedrock concatenated buffer. + let bedrockBuffer: Uint8Array = new Uint8Array(0); + function readOpenAI() { reader .read() .then(({ done, value }: { done: boolean; value?: Uint8Array }) => { try { if (done) { + if (openAIBuffer) { + chunks.push(getOpenAIChunks([openAIBuffer])[0]); + } observer.next({ chunks, - message: getMessageFromChunks(chunks), + message: chunks.join(''), loading: false, }); observer.complete(); return; } + const decoded = decoder.decode(value); - const content = isError - ? // we format errors as {message: string; status_code: number} - `${API_ERROR}\n\n${JSON.parse(decoded).message}` - : // all other responses are just strings (handled by subaction invokeStream) - decoded; - chunks.push(content); - observer.next({ - chunks, - message: getMessageFromChunks(chunks), - loading: true, + let nextChunks; + if (isError) { + nextChunks = [`${API_ERROR}\n\n${JSON.parse(decoded).message}`]; + } else { + const lines = decoded.split('\n'); + lines[0] = openAIBuffer + lines[0]; + openAIBuffer = lines.pop() || ''; + nextChunks = getOpenAIChunks(lines); + } + nextChunks.forEach((chunk: string) => { + chunks.push(chunk); + observer.next({ + chunks, + message: chunks.join(''), + loading: true, + }); }); } catch (err) { observer.error(err); return; } - read(); + readOpenAI(); + }) + .catch((err) => { + observer.error(err); + }); + } + function readBedrock() { + reader + .read() + .then(({ done, value }: { done: boolean; value?: Uint8Array }) => { + try { + if (done) { + observer.next({ + chunks, + message: chunks.join(''), + loading: false, + }); + observer.complete(); + return; + } + + let content; + if (isError) { + content = `${API_ERROR}\n\n${JSON.parse(decoder.decode(value)).message}`; + chunks.push(content); + observer.next({ + chunks, + message: chunks.join(''), + loading: true, + }); + } else if (value != null) { + const chunk: Uint8Array = value; + + // Concatenate the current chunk to the existing buffer. + bedrockBuffer = concatChunks(bedrockBuffer, chunk); + // Get the length of the next message in the buffer. + let messageLength = getMessageLength(bedrockBuffer); + + // Initialize an array to store fully formed message chunks. + const buildChunks = []; + // Process the buffer until no complete messages are left. + while (bedrockBuffer.byteLength > 0 && bedrockBuffer.byteLength >= messageLength) { + // Extract a chunk of the specified length from the buffer. + const extractedChunk = bedrockBuffer.slice(0, messageLength); + // Add the extracted chunk to the array of fully formed message chunks. + buildChunks.push(extractedChunk); + // Remove the processed chunk from the buffer. + bedrockBuffer = bedrockBuffer.slice(messageLength); + // Get the length of the next message in the updated buffer. + messageLength = getMessageLength(bedrockBuffer); + } + + const awsDecoder = new EventStreamCodec(toUtf8, fromUtf8); + // Decode and parse each message chunk, extracting the 'completion' property. + buildChunks.forEach((bChunk) => { + const event = awsDecoder.decode(bChunk); + const body = JSON.parse( + Buffer.from(JSON.parse(decoder.decode(event.body)).bytes, 'base64').toString() + ); + content = body.completion; + chunks.push(content); + observer.next({ + chunks, + message: chunks.join(''), + loading: true, + }); + }); + } + } catch (err) { + observer.error(err); + return; + } + readBedrock(); }) .catch((err) => { observer.error(err); }); } - read(); + // this should never actually happen + function badConnector() { + observer.next({ + chunks: [ + `Invalid connector type - ${connectorTypeTitle} is not a supported GenAI connector.`, + ], + message: `Invalid connector type - ${connectorTypeTitle} is not a supported GenAI connector.`, + loading: false, + }); + observer.complete(); + } + + if (connectorTypeTitle === 'Amazon Bedrock') readBedrock(); + else if (connectorTypeTitle === 'OpenAI') readOpenAI(); + else badConnector(); + return () => { reader.cancel(); }; @@ -99,8 +210,55 @@ export const getStreamObservable = ( finalize(() => setLoading(false)) ); -function getMessageFromChunks(chunks: string[]) { - return chunks.join(''); +/** + * Parses an OpenAI response from a string. + * @param lines + * @returns {string[]} - Parsed string array from the OpenAI response. + */ +const getOpenAIChunks = (lines: string[]): string[] => { + const nextChunk = lines + .map((str) => str.substring(6)) + .filter((str) => !!str && str !== '[DONE]') + .map((line) => { + try { + const openaiResponse = JSON.parse(line); + return openaiResponse.choices[0]?.delta.content ?? ''; + } catch (err) { + return ''; + } + }); + return nextChunk; +}; + +/** + * Concatenates two Uint8Array buffers. + * + * @param {Uint8Array} a - First buffer. + * @param {Uint8Array} b - Second buffer. + * @returns {Uint8Array} - Concatenated buffer. + */ +function concatChunks(a: Uint8Array, b: Uint8Array): Uint8Array { + const newBuffer = new Uint8Array(a.length + b.length); + // Copy the contents of the first buffer to the new buffer. + newBuffer.set(a); + // Copy the contents of the second buffer to the new buffer starting from the end of the first buffer. + newBuffer.set(b, a.length); + return newBuffer; +} + +/** + * Gets the length of the next message from the buffer. + * + * @param {Uint8Array} buffer - Buffer containing the message. + * @returns {number} - Length of the next message. + */ +function getMessageLength(buffer: Uint8Array): number { + // If the buffer is empty, return 0. + if (buffer.byteLength === 0) return 0; + // Create a DataView to read the Uint32 value at the beginning of the buffer. + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + // Read and return the Uint32 value (message length). + return view.getUint32(0, false); } export const getPlaceholderObservable = () => new Observable(); diff --git a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.test.tsx b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.test.tsx index efbc61999f2c..c4f99884aa04 100644 --- a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.test.tsx +++ b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.test.tsx @@ -11,20 +11,22 @@ import { useStream } from './use_stream'; const amendMessage = jest.fn(); const reader = jest.fn(); const cancel = jest.fn(); +const chunk1 = `data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"My"}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" new"}}]}`; +const chunk2 = `\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" message"}}]}\ndata: [DONE]`; const readerComplete = { read: reader .mockResolvedValueOnce({ done: false, - value: new Uint8Array(new TextEncoder().encode('one chunk ')), + value: new Uint8Array(new TextEncoder().encode(chunk1)), }) .mockResolvedValueOnce({ done: false, - value: new Uint8Array(new TextEncoder().encode(`another chunk`)), + value: new Uint8Array(new TextEncoder().encode(chunk2)), }) .mockResolvedValueOnce({ done: false, - value: new Uint8Array(new TextEncoder().encode(``)), + value: new Uint8Array(new TextEncoder().encode('')), }) .mockResolvedValue({ done: true, @@ -34,7 +36,12 @@ const readerComplete = { closed: jest.fn().mockResolvedValue(true), } as unknown as ReadableStreamDefaultReader; -const defaultProps = { amendMessage, reader: readerComplete, isError: false }; +const defaultProps = { + amendMessage, + reader: readerComplete, + isError: false, + connectorTypeTitle: 'OpenAI', +}; describe('useStream', () => { beforeEach(() => { jest.clearAllMocks(); @@ -57,7 +64,7 @@ describe('useStream', () => { error: undefined, isLoading: true, isStreaming: true, - pendingMessage: 'one chunk ', + pendingMessage: 'My', setComplete: expect.any(Function), }); }); @@ -67,7 +74,7 @@ describe('useStream', () => { error: undefined, isLoading: false, isStreaming: false, - pendingMessage: 'one chunk another chunk', + pendingMessage: 'My new message', setComplete: expect.any(Function), }); }); diff --git a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.tsx b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.tsx index 7de06589f87c..9271758a8558 100644 --- a/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.tsx +++ b/x-pack/plugins/security_solution/public/assistant/get_comments/stream/use_stream.tsx @@ -7,13 +7,13 @@ import { useCallback, useEffect, useMemo, useState } from 'react'; import type { Subscription } from 'rxjs'; -import { share } from 'rxjs'; import { getPlaceholderObservable, getStreamObservable } from './stream_observable'; interface UseStreamProps { amendMessage: (message: string) => void; isError: boolean; content?: string; + connectorTypeTitle: string; reader?: ReadableStreamDefaultReader; } interface UseStream { @@ -39,6 +39,7 @@ interface UseStream { export const useStream = ({ amendMessage, content, + connectorTypeTitle, reader, isError, }: UseStreamProps): UseStream => { @@ -49,9 +50,9 @@ export const useStream = ({ const observer$ = useMemo( () => content == null && reader != null - ? getStreamObservable(reader, setLoading, isError) + ? getStreamObservable({ connectorTypeTitle, reader, setLoading, isError }) : getPlaceholderObservable(), - [content, isError, reader] + [content, isError, reader, connectorTypeTitle] ); const onCompleteStream = useCallback(() => { subscription?.unsubscribe(); @@ -66,7 +67,7 @@ export const useStream = ({ } }, [complete, onCompleteStream]); useEffect(() => { - const newSubscription = observer$.pipe(share()).subscribe({ + const newSubscription = observer$.subscribe({ next: ({ message, loading: isLoading }) => { setLoading(isLoading); setPendingMessage(message); diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/insights/related_alerts_upsell.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/insights/related_alerts_upsell.tsx index 303e55ff66b9..10a9c872e391 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/insights/related_alerts_upsell.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/insights/related_alerts_upsell.tsx @@ -6,17 +6,11 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiText } from '@elastic/eui'; import { euiStyled } from '@kbn/kibana-react-plugin/common'; -import { SubscriptionLink } from '@kbn/subscription-tracking'; -import type { SubscriptionContextData } from '@kbn/subscription-tracking'; import { INSIGHTS_UPSELL } from './translations'; - -const subscriptionContext: SubscriptionContextData = { - feature: 'alert-details-insights', - source: 'security__alert-details-flyout', -}; +import { useKibana } from '../../../lib/kibana'; const UpsellContainer = euiStyled.div` border: 1px solid ${({ theme }) => theme.eui.euiColorLightShade}; @@ -29,6 +23,7 @@ const StyledIcon = euiStyled(EuiIcon)` `; export const RelatedAlertsUpsell = React.memo(() => { + const { application } = useKibana().services; return ( @@ -37,13 +32,15 @@ export const RelatedAlertsUpsell = React.memo(() => { - {INSIGHTS_UPSELL} - + diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/index.test.tsx index 968899a1e84d..9d676016be25 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/index.test.tsx @@ -7,51 +7,22 @@ import React from 'react'; import { render } from '@testing-library/react'; import { LandingPageComponent } from '.'; -import { useKibana } from '../../lib/kibana'; -import { Router } from 'react-router-dom'; -import { createBrowserHistory } from 'history'; -import { TestProviders } from '../../mock/test_providers'; -jest.mock('../../lib/kibana', () => ({ - useKibana: jest.fn(), +const mockUseContractComponents = jest.fn(() => ({})); +jest.mock('../../hooks/use_contract_component', () => ({ + useContractComponents: () => mockUseContractComponents(), })); -jest.mock('react-use/lib/useObservable', () => jest.fn((component) => component)); - describe('LandingPageComponent', () => { - const mockGetComponent = jest.fn(); - const history = createBrowserHistory(); - const mockSecuritySolutionTemplateWrapper = jest - .fn() - .mockImplementation(({ children }) =>
    {children}
    ); - - const renderPage = () => - render( - - - , - { wrapper: TestProviders } - ); - - beforeAll(() => { - (useKibana as jest.Mock).mockReturnValue({ - services: { - securityLayout: { - getPluginWrapper: jest.fn().mockReturnValue(mockSecuritySolutionTemplateWrapper), - }, - getComponent$: mockGetComponent, - }, - }); - }); - beforeEach(() => { jest.clearAllMocks(); }); it('renders the get started component', () => { - mockGetComponent.mockReturnValue(
    ); - const { queryByTestId } = renderPage(); + const GetStarted = () =>
    ; + mockUseContractComponents.mockReturnValue({ GetStarted }); + const { queryByTestId } = render(); - expect(queryByTestId('get-started')).toBeInTheDocument(); + expect(queryByTestId('get-started-mock')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/landing_page/index.tsx b/x-pack/plugins/security_solution/public/common/components/landing_page/index.tsx index d8e1a9029e21..959827aec3ba 100644 --- a/x-pack/plugins/security_solution/public/common/components/landing_page/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/landing_page/index.tsx @@ -6,13 +6,11 @@ */ import React, { memo } from 'react'; -import useObservable from 'react-use/lib/useObservable'; -import { useKibana } from '../../lib/kibana'; +import { useContractComponents } from '../../hooks/use_contract_component'; export const LandingPageComponent = memo(() => { - const { getComponent$ } = useKibana().services; - const GetStartedComponent = useObservable(getComponent$('getStarted')); - return <>{GetStartedComponent}; + const { GetStarted } = useContractComponents(); + return GetStarted ? : null; }); LandingPageComponent.displayName = 'LandingPageComponent'; diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_contract_component.ts b/x-pack/plugins/security_solution/public/common/hooks/use_contract_component.ts new file mode 100644 index 000000000000..2ebb46db35c8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/hooks/use_contract_component.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMemo } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { useKibana } from '../lib/kibana'; + +export const useContractComponents = () => { + const { getComponents$ } = useKibana().services; + const components$ = useMemo(() => getComponents$(), [getComponents$]); + return useObservable(components$, {}); +}; diff --git a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx index a6779272da76..03dc789a41ad 100644 --- a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx @@ -21,7 +21,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import type { Action } from '@kbn/ui-actions-plugin/public'; import { CellActionsProvider } from '@kbn/cell-actions'; import { ExpandableFlyoutProvider } from '@kbn/expandable-flyout'; -import { MockSubscriptionTrackingProvider } from '@kbn/subscription-tracking/mocks'; import { useKibana } from '../lib/kibana'; import { UpsellingProvider } from '../components/upselling_provider'; import { MockAssistantProvider } from './mock_assistant_provider'; @@ -76,29 +75,27 @@ export const TestProvidersComponent: React.FC = ({ return ( - - - - ({ eui: euiDarkVars, darkMode: true })}> - - - - - - Promise.resolve(cellActions)} - > - {children} - - - - - - - - - - + + + ({ eui: euiDarkVars, darkMode: true })}> + + + + + + Promise.resolve(cellActions)} + > + {children} + + + + + + + + + ); @@ -130,33 +127,31 @@ const TestProvidersWithPrivilegesComponent: React.FC = ({ return ( - - - ({ eui: euiDarkVars, darkMode: true })}> - - - - + ({ eui: euiDarkVars, darkMode: true })}> + + + + + Promise.resolve(cellActions)} > - Promise.resolve(cellActions)} - > - {children} - - - - - - - - + {children} + + + + + + + ); diff --git a/x-pack/plugins/security_solution/public/contract_components.ts b/x-pack/plugins/security_solution/public/contract_components.ts index 91e341c4120f..3d1dee67eab9 100644 --- a/x-pack/plugins/security_solution/public/contract_components.ts +++ b/x-pack/plugins/security_solution/public/contract_components.ts @@ -5,17 +5,16 @@ * 2.0. */ -import { BehaviorSubject, map } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import type { Observable } from 'rxjs'; -export type ContractComponentName = 'getStarted' | 'dashboardsLandingCallout'; - -export type ContractComponents = Partial>; +export type ContractComponents = Partial<{ + GetStarted: React.ComponentType<{}>; + DashboardsLandingCallout: React.ComponentType<{}>; +}>; export type SetComponents = (components: ContractComponents) => void; -export type GetComponent$ = ( - name: ContractComponentName -) => Observable; +export type GetComponents$ = () => Observable; export class ContractComponentsService { private components$: BehaviorSubject; @@ -28,6 +27,5 @@ export class ContractComponentsService { this.components$.next(components); }; - public getComponent$: GetComponent$ = (name) => - this.components$.pipe(map((components) => components[name])); + public getComponents$ = () => this.components$.asObservable(); } diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx index 8723bfb69f32..52e6692de104 100644 --- a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.test.tsx @@ -28,11 +28,9 @@ jest.mock('@kbn/dashboard-plugin/public', () => ({ DashboardTopNav: jest.fn().mockReturnValue(), })); -const mockUseObservable = jest.fn(); - -jest.mock('react-use', () => ({ - ...jest.requireActual('react-use'), - useObservable: () => mockUseObservable(), +const mockUseContractComponents = jest.fn(() => ({})); +jest.mock('../../../common/hooks/use_contract_component', () => ({ + useContractComponents: () => mockUseContractComponents(), })); const DEFAULT_DASHBOARD_CAPABILITIES = { show: true, createNew: true }; @@ -216,11 +214,11 @@ describe('Dashboards landing', () => { }); it('should render callout when available', async () => { - const DummyComponent = () => ; - mockUseObservable.mockReturnValue(); + const DashboardsLandingCallout = () => ; + mockUseContractComponents.mockReturnValue({ DashboardsLandingCallout }); await renderDashboardLanding(); - expect(screen.queryByTestId('test')).toBeInTheDocument(); + expect(screen.queryByTestId('callout-test')).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx index 10fb3c060548..affe83b0682c 100644 --- a/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx +++ b/x-pack/plugins/security_solution/public/dashboards/pages/landing_page/index.tsx @@ -17,11 +17,11 @@ import React, { useCallback, useMemo } from 'react'; import type { DashboardCapabilities } from '@kbn/dashboard-plugin/common/types'; import { DashboardListingTable, LEGACY_DASHBOARD_APP_ID } from '@kbn/dashboard-plugin/public'; import { LandingLinksImageCards } from '@kbn/security-solution-navigation/landing_links'; -import { useObservable } from 'react-use'; +import { useContractComponents } from '../../../common/hooks/use_contract_component'; import { SecuritySolutionPageWrapper } from '../../../common/components/page_wrapper'; import { SpyRoute } from '../../../common/utils/route/spy_routes'; import { SecurityPageName } from '../../../../common/constants'; -import { useCapabilities, useKibana, useNavigateTo } from '../../../common/lib/kibana'; +import { useCapabilities, useNavigateTo } from '../../../common/lib/kibana'; import { useRootNavLink } from '../../../common/links/nav_links'; import { Title } from '../../../common/components/header_page/title'; import { LinkButton } from '../../../common/components/links/helpers'; @@ -83,8 +83,7 @@ const Header: React.FC<{ canCreateDashboard: boolean }> = ({ canCreateDashboard }; export const DashboardsLandingPage = () => { - const { getComponent$ } = useKibana().services; - const dashboardLandingCallout = useObservable(getComponent$('dashboardsLandingCallout')); + const { DashboardsLandingCallout } = useContractComponents(); const { links = [] } = useRootNavLink(SecurityPageName.dashboards) ?? {}; const urlState = useGlobalQueryString(); const { show: canReadDashboard, createNew: canCreateDashboard } = @@ -122,9 +121,9 @@ export const DashboardsLandingPage = () => {
    - {dashboardLandingCallout && ( + {DashboardsLandingCallout && ( <> - {dashboardLandingCallout} + )} diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx index bd0b0e262e3c..703ed94a8c61 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/risk_score_enable_section.tsx @@ -29,11 +29,8 @@ import { EuiAccordion, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { - DETECTION_ENTITY_DASHBOARD, - RISKY_HOSTS_DOC_LINK, - RISKY_USERS_DOC_LINK, -} from '../../../common/constants'; +import { LinkAnchor } from '@kbn/security-solution-navigation/links'; +import { SecurityPageName } from '@kbn/security-solution-navigation'; import * as i18n from '../translations'; import { useRiskEngineStatus } from '../api/hooks/use_risk_engine_status'; import { useInitRiskEngineMutation } from '../api/hooks/use_init_risk_engine_mutation'; @@ -41,20 +38,8 @@ import { useEnableRiskEngineMutation } from '../api/hooks/use_enable_risk_engine import { useDisableRiskEngineMutation } from '../api/hooks/use_disable_risk_engine_mutation'; import { RiskEngineStatus, MAX_SPACES_COUNT } from '../../../common/risk_engine'; -const docsLinks = [ - { - link: DETECTION_ENTITY_DASHBOARD, - label: i18n.EA_DOCS_DASHBOARD, - }, - { - link: RISKY_HOSTS_DOC_LINK, - label: i18n.EA_DOCS_RISK_HOSTS, - }, - { - link: RISKY_USERS_DOC_LINK, - label: i18n.EA_DOCS_RISK_USERS, - }, -]; +import { RiskInformationFlyout } from '../../explore/components/risk_score/risk_information'; +import { useOnOpenCloseHandler } from '../../helper_hooks'; const MIN_WIDTH_TO_PREVENT_LABEL_FROM_MOVING = '50px'; @@ -209,6 +194,8 @@ export const RiskScoreEnableSection = () => { const closeModal = () => setIsModalVisible(false); const showModal = () => setIsModalVisible(true); + const [isFlyoutVisible, handleOnOpen, handleOnClose] = useOnOpenCloseHandler(); + const isLoading = initRiskEngineMutation.isLoading || enableRiskEngineMutation.isLoading || @@ -345,14 +332,17 @@ export const RiskScoreEnableSection = () => {
      - {docsLinks.map(({ link, label }) => ( -
    • - - {label} - - -
    • - ))} +
    • + {i18n.EA_DASHBOARD_LINK} + +
    • +
    • + + {i18n.EA_DOCS_ENTITY_RISK_SCORE} + + {isFlyoutVisible && } + +
    diff --git a/x-pack/plugins/security_solution/public/entity_analytics/translations.ts b/x-pack/plugins/security_solution/public/entity_analytics/translations.ts index e22833674ff8..06880dbdd4ae 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/translations.ts +++ b/x-pack/plugins/security_solution/public/entity_analytics/translations.ts @@ -59,7 +59,7 @@ export const RISK_SCORE_MODULE_STATUS_OFF = i18n.translate( export const ENTITY_RISK_SCORING = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.entityRiskScoring', { - defaultMessage: 'Entity risk scoring', + defaultMessage: 'Entity risk score', } ); @@ -70,10 +70,10 @@ export const USEFUL_LINKS = i18n.translate( } ); -export const EA_DOCS_DASHBOARD = i18n.translate( +export const EA_DASHBOARD_LINK = i18n.translate( 'xpack.securitySolution.riskScore.riskScorePreview.eaDocsDashboard', { - defaultMessage: 'Entity Analytics documentation', + defaultMessage: 'Entity Analytics dashboard', } ); @@ -91,6 +91,13 @@ export const EA_DOCS_RISK_USERS = i18n.translate( } ); +export const EA_DOCS_ENTITY_RISK_SCORE = i18n.translate( + 'xpack.securitySolution.riskScore.riskScorePreview.eaDocsEntities', + { + defaultMessage: 'How is the risk score calculated?', + } +); + export const PREVIEW = i18n.translate('xpack.securitySolution.riskScore.riskScorePreview.preview', { defaultMessage: 'Preview', }); diff --git a/x-pack/plugins/security_solution/public/exceptions/hooks/use_endpoint_exceptions_capability/index.tsx b/x-pack/plugins/security_solution/public/exceptions/hooks/use_endpoint_exceptions_capability/index.tsx index a96b11225e65..4b107a5c681c 100644 --- a/x-pack/plugins/security_solution/public/exceptions/hooks/use_endpoint_exceptions_capability/index.tsx +++ b/x-pack/plugins/security_solution/public/exceptions/hooks/use_endpoint_exceptions_capability/index.tsx @@ -5,19 +5,10 @@ * 2.0. */ -import { useMemo } from 'react'; -import { useListsConfig } from '../../../detections/containers/detection_engine/lists/use_lists_config'; import { useHasSecurityCapability } from '../../../helper_hooks'; export const useEndpointExceptionsCapability = ( capability: 'showEndpointExceptions' | 'crudEndpointExceptions' -) => { - const { loading: listsConfigLoading, needsConfiguration: needsListsConfiguration } = - useListsConfig(); - const hasEndpointExceptionCapability = useHasSecurityCapability(capability); - - return useMemo( - () => !listsConfigLoading && !needsListsConfiguration && hasEndpointExceptionCapability, - [hasEndpointExceptionCapability, listsConfigLoading, needsListsConfiguration] - ); +): boolean => { + return useHasSecurityCapability(capability); }; diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx index 4edecf5c4017..bd099341419f 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/index.tsx @@ -28,7 +28,7 @@ import { import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { css } from '@emotion/react'; -import { getRiskEntityTranslation } from '../translations'; + import * as i18n from './translations'; import { useOnOpenCloseHandler } from '../../../../helper_hooks'; import { RiskScoreLevel } from '../severity/common'; @@ -36,7 +36,7 @@ import { RiskScoreEntity, RiskSeverity } from '../../../../../common/search_stra import { RiskScoreDocLink } from '../risk_score_onboarding/risk_score_doc_link'; import { BETA } from '../risk_score_onboarding/translations'; -const getTableColumns = (riskEntity: RiskScoreEntity): Array> => [ +const getTableColumns = (riskEntity?: RiskScoreEntity): Array> => [ { field: 'level', name: i18n.INFORMATION_LEVEL_HEADER, @@ -85,9 +85,7 @@ export const RiskInformationButtonIcon = ({ riskEntity }: { riskEntity: RiskScor } data-test-subj="open-risk-information-flyout-trigger" /> - {isFlyoutVisible && ( - - )} + {isFlyoutVisible && } ); }; @@ -100,20 +98,12 @@ export const RiskInformationButtonEmpty = ({ riskEntity }: { riskEntity: RiskSco {i18n.INFO_BUTTON_TEXT} - {isFlyoutVisible && ( - - )} + {isFlyoutVisible && } ); }; -const RiskInformationFlyout = ({ - handleOnClose, - riskEntity, -}: { - handleOnClose: () => void; - riskEntity: RiskScoreEntity; -}) => { +export const RiskInformationFlyout = ({ handleOnClose }: { handleOnClose: () => void }) => { const { euiTheme } = useEuiTheme(); const simpleFlyoutTitleId = useGeneratedHtmlId({ prefix: 'RiskInformation', @@ -157,15 +147,13 @@ const RiskInformationFlyout = ({

    ), @@ -176,15 +164,13 @@ const RiskInformationFlyout = ({ ), @@ -236,26 +222,22 @@ const RiskInformationFlyout = ({

    } /> diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts index 112c6d37ca4a..20fa22bbc26f 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts +++ b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_information/translations.ts @@ -23,7 +23,7 @@ export const INFORMATION_ARIA_LABEL = i18n.translate( } ); -export const INFORMATION_RISK_HEADER = (riskEntity: RiskScoreEntity) => +export const INFORMATION_RISK_HEADER = (riskEntity?: RiskScoreEntity) => i18n.translate('xpack.securitySolution.riskInformation.riskHeader', { defaultMessage: '{riskEntity} risk score range', values: { diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx index cae89799d2d1..dbe56fd74931 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx +++ b/x-pack/plugins/security_solution/public/explore/components/risk_score/risk_score_onboarding/risk_score_doc_link.tsx @@ -6,20 +6,31 @@ */ import { EuiLink } from '@elastic/eui'; -import React from 'react'; +import React, { useMemo } from 'react'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; -import { RISKY_HOSTS_DOC_LINK, RISKY_USERS_DOC_LINK } from '../../../../../common/constants'; +import { + RISKY_HOSTS_DOC_LINK, + RISKY_USERS_DOC_LINK, + RISKY_ENTITY_SCORE_DOC_LINK, +} from '../../../../../common/constants'; import { LEARN_MORE } from '../../../../overview/components/entity_analytics/risk_score/translations'; const RiskScoreDocLinkComponent = ({ riskScoreEntity, title, }: { - riskScoreEntity: RiskScoreEntity; + riskScoreEntity?: RiskScoreEntity; title?: string | React.ReactNode; }) => { - const docLink = - riskScoreEntity === RiskScoreEntity.user ? RISKY_USERS_DOC_LINK : RISKY_HOSTS_DOC_LINK; + const docLink = useMemo(() => { + if (!riskScoreEntity) { + return RISKY_ENTITY_SCORE_DOC_LINK; + } + if (riskScoreEntity === RiskScoreEntity.user) { + return RISKY_USERS_DOC_LINK; + } + return RISKY_HOSTS_DOC_LINK; + }, [riskScoreEntity]); return ( diff --git a/x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts b/x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts index 501de5719a63..d072607544d4 100644 --- a/x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts +++ b/x-pack/plugins/security_solution/public/explore/components/risk_score/translations.ts @@ -24,6 +24,14 @@ export const USERS = i18n.translate('xpack.securitySolution.riskScore.overview.u defaultMessage: 'Users', }); +export const ENTITY = i18n.translate('xpack.securitySolution.riskScore.overview.entityTitle', { + defaultMessage: 'Entity', +}); + +export const ENTITIES = i18n.translate('xpack.securitySolution.riskScore.overview.entities', { + defaultMessage: 'Entities', +}); + export const RISK_SCORE_TITLE = (riskEntity: RiskScoreEntity) => i18n.translate('xpack.securitySolution.riskScore.overview.riskScoreTitle', { defaultMessage: '{riskEntity} Risk Score', @@ -41,22 +49,26 @@ export const ENTITY_RISK_LEVEL = (riskEntity: RiskScoreEntity) => }); export const getRiskEntityTranslation = ( - riskEntity: RiskScoreEntity, + riskEntity?: RiskScoreEntity, lowercase = false, plural = false ) => { - if (lowercase) { - if (plural) { - return (riskEntity === RiskScoreEntity.host ? HOSTS : USERS).toLowerCase(); - } + const text = getRiskEntityTranslationText(riskEntity, plural); + return lowercase ? text.toLowerCase() : text; +}; - return (riskEntity === RiskScoreEntity.host ? HOST : USER).toLowerCase(); - } - if (plural) { - return riskEntity === RiskScoreEntity.host ? HOSTS : USERS; +export const getRiskEntityTranslationText = ( + riskEntity: RiskScoreEntity | undefined, + plural: boolean +) => { + switch (riskEntity) { + case RiskScoreEntity.host: + return plural ? HOSTS : HOST; + case RiskScoreEntity.user: + return plural ? USERS : USER; + default: + return plural ? ENTITIES : ENTITY; } - - return riskEntity === RiskScoreEntity.host ? HOST : USER; }; export const ALERTS = i18n.translate('xpack.securitySolution.riskScore.overview.alerts', { diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx index ac7422619ee0..d872eee2d2ce 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/criteria_conditions.tsx @@ -17,6 +17,7 @@ import { OS_WINDOWS, CONDITION_AND, CONDITION_OPERATOR_TYPE_WILDCARD_MATCHES, + CONDITION_OPERATOR_TYPE_DOES_NOT_MATCH, CONDITION_OPERATOR_TYPE_NESTED, CONDITION_OPERATOR_TYPE_MATCH, CONDITION_OPERATOR_TYPE_MATCH_ANY, @@ -47,6 +48,7 @@ const OPERATOR_TYPE_LABELS_INCLUDED = Object.freeze({ const OPERATOR_TYPE_LABELS_EXCLUDED = Object.freeze({ [ListOperatorTypeEnum.MATCH_ANY]: CONDITION_OPERATOR_TYPE_NOT_MATCH_ANY, [ListOperatorTypeEnum.MATCH]: CONDITION_OPERATOR_TYPE_NOT_MATCH, + [ListOperatorTypeEnum.WILDCARD]: CONDITION_OPERATOR_TYPE_DOES_NOT_MATCH, }); const EuiFlexGroupNested = styled(EuiFlexGroup)` diff --git a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts index 273cda46aa72..2024541091d5 100644 --- a/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts +++ b/x-pack/plugins/security_solution/public/management/components/artifact_entry_card/components/translations.ts @@ -68,6 +68,13 @@ export const CONDITION_OPERATOR_TYPE_WILDCARD_MATCHES = i18n.translate( } ); +export const CONDITION_OPERATOR_TYPE_DOES_NOT_MATCH = i18n.translate( + 'xpack.securitySolution.artifactCard.conditions.wildcardDoesNotMatchOperator', + { + defaultMessage: 'DOES NOT MATCH', + } +); + export const CONDITION_OPERATOR_TYPE_NESTED = i18n.translate( 'xpack.securitySolution.artifactCard.conditions.nestedOperator', { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolation.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts similarity index 51% rename from x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolation.cy.ts rename to x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts index 5b0d198742ed..44fdf9d63fb6 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolation.cy.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/isolate.cy.ts @@ -19,7 +19,6 @@ import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../../t import { checkEndpointListForOnlyIsolatedHosts, checkEndpointListForOnlyUnIsolatedHosts, - isolateHostFromEndpointList, } from '../../../tasks/isolate'; import { login } from '../../../tasks/login'; @@ -27,59 +26,44 @@ import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; import { createEndpointHost } from '../../../tasks/create_endpoint_host'; import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; -// Failing: See https://github.com/elastic/kibana/issues/170470 -describe.skip('Response console', { tags: ['@ess', '@serverless'] }, () => { - beforeEach(() => { - login(); - }); - - describe('Host Isolation:', () => { - let indexedPolicy: IndexedFleetEndpointPolicyResponse; - let policy: PolicyData; - let createdHost: CreateAndEnrollEndpointHostResponse; +describe('Response console', { tags: ['@ess', '@serverless'] }, () => { + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; - before(() => { - getEndpointIntegrationVersion().then((version) => - createAgentPolicyTask(version).then((data) => { - indexedPolicy = data; - policy = indexedPolicy.integrationPolicies[0]; + before(() => { + getEndpointIntegrationVersion().then((version) => + createAgentPolicyTask(version).then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; - return enableAllPolicyProtections(policy.id).then(() => { - // Create and enroll a new Endpoint host - return createEndpointHost(policy.policy_id).then((host) => { - createdHost = host as CreateAndEnrollEndpointHostResponse; - }); + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; }); - }) - ); - }); + }); + }) + ); + }); - after(() => { - if (createdHost) { - cy.task('destroyEndpointHost', createdHost); - } + after(() => { + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } - if (indexedPolicy) { - cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); - } + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } - if (createdHost) { - deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); - } - }); + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } + }); - it('should release an isolated host from response console', () => { - const command = 'release'; - waitForEndpointListPageToBeLoaded(createdHost.hostname); - // isolate the host first - isolateHostFromEndpointList(); - checkEndpointListForOnlyIsolatedHosts(); - openResponseConsoleFromEndpointList(); - performCommandInputChecks(command); - submitCommand(); - waitForCommandToBeExecuted(command); - waitForEndpointListPageToBeLoaded(createdHost.hostname); - checkEndpointListForOnlyUnIsolatedHosts(); + describe('Host Isolation:', () => { + beforeEach(() => { + login(); }); it('should isolate a host from response console', () => { diff --git a/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/release.cy.ts b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/release.cy.ts new file mode 100644 index 000000000000..8de8ca22ae8b --- /dev/null +++ b/x-pack/plugins/security_solution/public/management/cypress/e2e/response_actions/response_console/release.cy.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PolicyData } from '../../../../../../common/endpoint/types'; +import type { CreateAndEnrollEndpointHostResponse } from '../../../../../../scripts/endpoint/common/endpoint_host_services'; +import { + openResponseConsoleFromEndpointList, + performCommandInputChecks, + submitCommand, + waitForCommandToBeExecuted, + waitForEndpointListPageToBeLoaded, +} from '../../../tasks/response_console'; +import type { IndexedFleetEndpointPolicyResponse } from '../../../../../../common/endpoint/data_loaders/index_fleet_endpoint_policy'; +import { createAgentPolicyTask, getEndpointIntegrationVersion } from '../../../tasks/fleet'; +import { + checkEndpointListForOnlyIsolatedHosts, + checkEndpointListForOnlyUnIsolatedHosts, + isolateHostActionViaAPI, +} from '../../../tasks/isolate'; + +import { login } from '../../../tasks/login'; +import { enableAllPolicyProtections } from '../../../tasks/endpoint_policy'; +import { createEndpointHost } from '../../../tasks/create_endpoint_host'; +import { deleteAllLoadedEndpointData } from '../../../tasks/delete_all_endpoint_data'; + +describe('Response console', { tags: ['@ess', '@serverless'] }, () => { + let indexedPolicy: IndexedFleetEndpointPolicyResponse; + let policy: PolicyData; + let createdHost: CreateAndEnrollEndpointHostResponse; + + before(() => { + getEndpointIntegrationVersion().then((version) => + createAgentPolicyTask(version).then((data) => { + indexedPolicy = data; + policy = indexedPolicy.integrationPolicies[0]; + + return enableAllPolicyProtections(policy.id).then(() => { + // Create and enroll a new Endpoint host + return createEndpointHost(policy.policy_id).then((host) => { + createdHost = host as CreateAndEnrollEndpointHostResponse; + }); + }); + }) + ); + }); + + after(() => { + if (createdHost) { + cy.task('destroyEndpointHost', createdHost); + } + + if (indexedPolicy) { + cy.task('deleteIndexedFleetEndpointPolicies', indexedPolicy); + } + + if (createdHost) { + deleteAllLoadedEndpointData({ endpointAgentIds: [createdHost.agentId] }); + } + }); + + describe('Host Isolation:', () => { + beforeEach(() => { + login(); + }); + + it('should release an isolated host via response console', () => { + const command = 'release'; + waitForEndpointListPageToBeLoaded(createdHost.hostname); + // isolate the host first + isolateHostActionViaAPI(createdHost.agentId); + // verify and find the isolated host + checkEndpointListForOnlyIsolatedHosts(); + openResponseConsoleFromEndpointList(); + performCommandInputChecks(command); + submitCommand(); + waitForCommandToBeExecuted(command); + waitForEndpointListPageToBeLoaded(createdHost.hostname); + checkEndpointListForOnlyUnIsolatedHosts(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts index 10aec51af291..20d57ba7a94b 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/isolate.ts @@ -7,9 +7,11 @@ /* eslint-disable cypress/no-unnecessary-waiting */ +import { API_VERSIONS } from '@kbn/fleet-plugin/common'; import { openAlertDetailsView } from '../screens/alerts'; import type { ActionDetails } from '../../../../common/endpoint/types'; import { loadPage } from './common'; +import { waitForActionToSucceed } from './response_actions'; const API_ENDPOINT_ACTION_PATH = '/api/endpoint/action/*'; export const interceptActionRequests = ( @@ -41,29 +43,6 @@ export const isolateHostWithComment = (comment: string, hostname: string): void cy.getByTestSubj('host_isolation_comment').type(comment); }; -export const isolateHostFromEndpointList = (index: number = 0): void => { - // open the action menu and click isolate action - cy.getByTestSubj('endpointTableRowActions').eq(index).click(); - cy.getByTestSubj('isolateLink').click(); - // isolation form, click confirm button - cy.getByTestSubj('hostIsolateConfirmButton').click(); - // return to endpoint details - cy.getByTestSubj('hostIsolateSuccessCompleteButton').click(); - // close details flyout - cy.getByTestSubj('euiFlyoutCloseButton').click(); - - // ensure the host is isolated, wait for 3 minutes for the host to be isolated - cy.wait(18000); - - cy.getByTestSubj('endpointListTable').within(() => { - cy.get('tbody tr') - .eq(index) - .within(() => { - cy.get('td').eq(1).should('contain.text', 'Isolated'); - }); - }); -}; - export const releaseHostWithComment = (comment: string, hostname: string): void => { cy.contains(`${hostname} is currently isolated.`); cy.getByTestSubj('endpointHostIsolationForm'); @@ -139,28 +118,46 @@ export const filterOutIsolatedHosts = (): void => { cy.getByTestSubj('querySubmitButton').click(); }; -const checkEndpointListForIsolatedHosts = (expectIsolated: boolean): void => { - const chainer = expectIsolated ? 'contain.text' : 'not.contain.text'; +const checkEndpointListForIsolationStatus = (expectIsolated: boolean): void => { + const chainer = expectIsolated ? 'contain' : 'not.contain'; cy.getByTestSubj('endpointListTable').within(() => { - cy.get('tbody tr').each(($tr) => { - cy.wrap($tr).within(() => { + cy.get('tbody tr') + .eq(0) + .within(() => { cy.get('td').eq(1).should(chainer, 'Isolated'); }); - }); }); }; export const checkEndpointListForOnlyUnIsolatedHosts = (): void => - checkEndpointListForIsolatedHosts(false); + checkEndpointListForIsolationStatus(false); export const checkEndpointListForOnlyIsolatedHosts = (): void => - checkEndpointListForIsolatedHosts(true); + checkEndpointListForIsolationStatus(true); + +export const isolateHostActionViaAPI = (agentId: string): void => { + cy.request({ + headers: { + 'kbn-xsrf': 'cypress-creds', + 'elastic-api-version': API_VERSIONS.public.v1, + }, + method: 'POST', + url: 'api/endpoint/action/isolate', + body: { + endpoint_ids: [agentId], + }, + }) + // verify action was successful + .then((response) => waitForActionToSucceed(response.body.data.id)) + .then((actionResponse) => { + expect(actionResponse.status).to.equal('successful'); + }); +}; export const checkEndpointIsolationStatus = ( endpointHostname: string, expectIsolated: boolean ): void => { - const chainer = expectIsolated ? 'contain.text' : 'not.contain.text'; - + const chainer = expectIsolated ? 'contain' : 'not.contain'; cy.contains(endpointHostname).parents('td').siblings('td').eq(0).should(chainer, 'Isolated'); }; diff --git a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts index 387f86c0dd16..126d637f07ed 100644 --- a/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts +++ b/x-pack/plugins/security_solution/public/management/cypress/tasks/response_actions.ts @@ -139,6 +139,38 @@ export const waitForActionToComplete = ( }); }; +export const waitForActionToSucceed = ( + actionId: string, + timeout = 180000 +): Cypress.Chainable => { + let action: ActionDetails | undefined; + + return cy + .waitUntil( + () => { + return request({ + method: 'GET', + url: resolvePathVariables(ACTION_DETAILS_ROUTE, { action_id: actionId || 'undefined' }), + }).then((response) => { + if (response.body.data.isCompleted && response.body.data.status === 'successful') { + action = response.body.data; + return true; + } + + return false; + }); + }, + { timeout, interval: 2000 } + ) + .then(() => { + if (!action) { + throw new Error('Failed to retrieve successful action'); + } + + return action; + }); +}; + /** * Ensure user has the given `accessLevel` to the type of response action * @param accessLevel diff --git a/x-pack/plugins/security_solution/public/mocks.ts b/x-pack/plugins/security_solution/public/mocks.ts index 044e58192f2d..6564697c95f0 100644 --- a/x-pack/plugins/security_solution/public/mocks.ts +++ b/x-pack/plugins/security_solution/public/mocks.ts @@ -16,7 +16,7 @@ const upselling = new UpsellingService(); export const contractStartServicesMock: ContractStartServices = { extraRoutes$: of([]), - getComponent$: jest.fn(), + getComponents$: jest.fn(() => of({})), upselling, }; diff --git a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts index f2e3296133ff..22fe8a3d5282 100644 --- a/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts +++ b/x-pack/plugins/security_solution/public/overview/components/entity_analytics/risk_score/translations.ts @@ -25,7 +25,7 @@ export const VIEW_ALL = i18n.translate( } ); -export const LEARN_MORE = (riskEntity: RiskScoreEntity) => +export const LEARN_MORE = (riskEntity?: RiskScoreEntity) => i18n.translate('xpack.securitySolution.entityAnalytics.riskDashboard.learnMore', { defaultMessage: 'Learn more about {riskEntity} risk', values: { diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index c07273e59ed4..e36dcd799172 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -235,11 +235,6 @@ export class Plugin implements IPlugin(({ timelineId }) => { - const isTimelineSaveTourSaveTourDisabled = - useIsExperimentalFeatureEnabled('disableTimelineSaveTour'); const [showEditTimelineOverlay, setShowEditTimelineOverlay] = useState(false); const closeSaveTimeline = useCallback(() => { @@ -56,9 +53,12 @@ export const SaveTimelineButton = React.memo(({ timelin } = useDeepEqualSelector((state) => getTimelineStatus(state, timelineId)); const isSaveButtonMounted = useIsElementMounted(SAVE_BUTTON_ELEMENT_ID); - const [hasSeenTimelineSaveTour, setHasSeenTimelineSaveTour] = useLocalStorage({ - defaultValue: false, + const [timelineTourStatus, setTimelineTourStatus] = useLocalStorage({ + defaultValue: { isTourActive: true }, key: LOCAL_STORAGE_KEY, + isInvalidDefault: (valueFromStorage) => { + return !valueFromStorage; + }, }); // Why are we checking for so many flags here? // The tour popup should only show when timeline is fully populated and all necessary @@ -66,17 +66,15 @@ export const SaveTimelineButton = React.memo(({ timelin // popup would show too early and in the wrong place in the DOM. // The last flag, checks if the tour has been dismissed before. const showTimelineSaveTour = - // The timeline save tour could be disabled on a plugin level - !isTimelineSaveTourSaveTourDisabled && canEditTimeline && isVisible && !isLoading && isSaveButtonMounted && - !hasSeenTimelineSaveTour; + timelineTourStatus?.isTourActive; const markTimelineSaveTourAsSeen = useCallback(() => { - setHasSeenTimelineSaveTour(true); - }, [setHasSeenTimelineSaveTour]); + setTimelineTourStatus({ isTourActive: false }); + }, [setTimelineTourStatus]); const isUnsaved = timelineStatus === TimelineStatus.draft; const tooltipContent = canEditTimeline ? null : timelineTranslations.CALL_OUT_UNAUTHORIZED_MSG; diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 0dcd00d3db78..16a75ce10526 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -81,7 +81,7 @@ import type { BreadcrumbsNav } from './common/breadcrumbs/types'; import type { TopValuesPopoverService } from './app/components/top_values_popover/top_values_popover_service'; import type { ExperimentalFeatures } from '../common/experimental_features'; import type { DeepLinksFormatter } from './common/links/deep_links'; -import type { SetComponents, GetComponent$ } from './contract_components'; +import type { SetComponents, GetComponents$ } from './contract_components'; import type { ConfigSettings } from '../common/config_settings'; export interface SetupPlugins { @@ -147,7 +147,7 @@ export interface StartPluginsDependencies extends StartPlugins { export interface ContractStartServices { extraRoutes$: Observable; - getComponent$: GetComponent$; + getComponents$: GetComponents$; upselling: UpsellingService; } diff --git a/x-pack/plugins/security_solution/scripts/junit_transformer/lib.ts b/x-pack/plugins/security_solution/scripts/junit_transformer/lib.ts index d9033c75d485..725baa689cd2 100644 --- a/x-pack/plugins/security_solution/scripts/junit_transformer/lib.ts +++ b/x-pack/plugins/security_solution/scripts/junit_transformer/lib.ts @@ -16,6 +16,7 @@ import * as t from 'io-ts'; import { isLeft } from 'fp-ts/lib/Either'; import { PathReporter } from 'io-ts/lib/PathReporter'; import globby from 'globby'; +import del from 'del'; /** * Updates the `name` and `classname` attributes of each testcase. @@ -195,6 +196,9 @@ ${boilerplate} if ('error' in maybeValidationResult) { logError(maybeValidationResult.error); + // Sending broken XML to Failed Test Reporter will cause a job to fail + await del(path); + log.warning(`${path} file was deleted.`); // If there is an error, continue trying to process other files. continue; } @@ -203,9 +207,11 @@ ${boilerplate} const { processed, hadTestCases } = isReportAlreadyProcessed(reportJson); if (hadTestCases === false) { - log.warning(`${path} had no test cases. Skipping it. + log.warning(`${path} had no test cases. ${boilerplate} `); + await del(path); + log.warning(`${path} file was deleted.`); // If there is an error, continue trying to process other files. continue; } @@ -222,6 +228,9 @@ ${boilerplate} if ('error' in maybeSpecFilePath) { logError(maybeSpecFilePath.error); + // Sending broken XML to Failed Test Reporter will cause a job to fail + await del(path); + log.warning(`${path} file was deleted.`); // If there is an error, continue trying to process other files. continue; } diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/get_ftr_config.ts b/x-pack/plugins/security_solution/scripts/run_cypress/get_ftr_config.ts index cc3972cba0b2..de5cb675a42e 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/get_ftr_config.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/get_ftr_config.ts @@ -171,17 +171,6 @@ export const getFTRConfig = ({ } } - // Serverless Specific - if (vars.serverless) { - log.info(`Serverless mode detected`); - - vars.esTestCluster.serverArgs.push( - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.entity_id=http://host.docker.internal:${kibanaPort}`, - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.logout=http://host.docker.internal:${kibanaPort}/logout`, - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.acs=http://host.docker.internal:${kibanaPort}/api/security/saml/callback` - ); - } - if (specFileFTRConfig?.productTypes) { if (vars.serverless) { vars.kbnTestServer.serverArgs.push( diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts index a64f4027f456..22b51692eb33 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts @@ -148,7 +148,8 @@ async function resetCredentials( apiKey: string ): Promise { log.info(`${runnerId} : Reseting credentials`); - try { + + const fetchResetCredentialsStatusAttempt = async (attemptNum: number) => { const response = await axios.post( `${BASE_ENV_URL}/api/v1/serverless/projects/security/${projectId}/_reset-credentials`, {}, @@ -158,13 +159,27 @@ async function resetCredentials( }, } ); + log.info('Credentials have ben reset'); return { password: response.data.password, username: response.data.username, }; - } catch (error) { - throw new Error(`${error.message}`); - } + }; + + const retryOptions = { + onFailedAttempt: (error: Error | AxiosError) => { + if (error instanceof AxiosError && error.code === 'ENOTFOUND') { + log.info('Project is not reachable. A retry will be triggered soon..'); + } else { + log.info(error); + } + }, + retries: 100, + factor: 2, + maxTimeout: 20000, + }; + + return pRetry(fetchResetCredentialsStatusAttempt, retryOptions); } // Wait until Project is initialized @@ -180,7 +195,7 @@ function waitForProjectInitialized(projectId: string, apiKey: string): Promise { if (error instanceof AxiosError && error.code === 'ENOTFOUND') { - log.info('Project is not reachable. Retrying in 20s...'); + log.info('Project is not reachable. A retry will be triggered soon...'); } else { log.info(error); } @@ -239,7 +254,7 @@ function waitForKibanaAvailable(kbUrl: string, auth: string, runnerId: string): }, }); if (response.data.status.overall.level !== 'available') { - throw new Error(`${runnerId}: Kibana is not available. Retrying in 20s...`); + throw new Error(`${runnerId}: Kibana is not available. A retry will be triggered soon...`); } else { log.info(`${runnerId}: Kibana status overall is ${response.data.status.overall.level}.`); } @@ -247,7 +262,9 @@ function waitForKibanaAvailable(kbUrl: string, auth: string, runnerId: string): const retryOptions = { onFailedAttempt: (error: Error | AxiosError) => { if (error instanceof AxiosError && error.code === 'ENOTFOUND') { - log.info(`${runnerId}: The Kibana URL is not yet reachable. Retrying in 20s...`); + log.info( + `${runnerId}: The Kibana URL is not yet reachable. A retry will be triggered soon...` + ); } else { log.info(`${runnerId}: ${error}`); } @@ -264,17 +281,11 @@ function waitForEsAccess(esUrl: string, auth: string, runnerId: string): Promise const fetchEsAccessAttempt = async (attemptNum: number) => { log.info(`Retry number ${attemptNum} to check if can be accessed.`); - const response = await axios.get(`${esUrl}`, { + await axios.get(`${esUrl}`, { headers: { Authorization: `Basic ${auth}`, }, }); - - if (response.status !== 200) { - throw new Error('Cannot access. Retrying in 20s...'); - } else { - log.info('Access performed successfully'); - } }; const retryOptions = { onFailedAttempt: (error: Error | AxiosError) => { @@ -302,19 +313,14 @@ function waitForKibanaLogin(kbUrl: string, credentials: Credentials): Promise { log.info(`Retry number ${attemptNum} to check if login can be performed.`); - const response = await axios.post(`${kbUrl}/internal/security/login`, body, { + axios.post(`${kbUrl}/internal/security/login`, body, { headers: API_HEADERS, }); - if (response.status !== 200) { - throw new Error('Cannot login. Retrying in 20s...'); - } else { - log.info('Login can be performed successfully'); - } }; const retryOptions = { onFailedAttempt: (error: Error | AxiosError) => { if (error instanceof AxiosError && error.code === 'ENOTFOUND') { - log.info('Project is not reachable. Retrying login in 20s...'); + log.info('Project is not reachable. A retry will be triggered soon...'); } else { log.info(error); } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts index 1404f8dba94e..50e0e0be47cd 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts @@ -9,6 +9,8 @@ export const TELEMETRY_CHANNEL_LISTS = 'security-lists-v2'; export const TELEMETRY_CHANNEL_ENDPOINT_META = 'endpoint-metadata'; +export const TELEMETRY_CHANNEL_ENDPOINT_ALERTS = 'alerts-endpoint'; + export const TELEMETRY_CHANNEL_DETECTION_ALERTS = 'alerts-detections'; export const TELEMETRY_CHANNEL_TIMELINE = 'alerts-timeline'; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/index.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/index.test.ts index d61a3e920681..5ccbb0f53a33 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/index.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/index.test.ts @@ -279,6 +279,25 @@ describe('Security Telemetry filters', () => { }); }); + it('copies over github integration fields', () => { + const event = { + not_event: 'much data, much wow', + github: { + org: 'elastic', + repo: 'kibana', + team: 'elastic/security-data-analytics', + sensitive: 'i contain sensitive data', + }, + }; + expect(copyAllowlistedFields(prebuiltRuleAllowlistFields, event)).toStrictEqual({ + github: { + org: 'elastic', + repo: 'kibana', + team: 'elastic/security-data-analytics', + }, + }); + }); + it('copies over process/parent fields', () => { const event = { not_event: 'much data, much wow', diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/prebuilt_rules_alerts.ts b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/prebuilt_rules_alerts.ts index c08c66a57224..a7e797227d24 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/prebuilt_rules_alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/filterlists/prebuilt_rules_alerts.ts @@ -350,6 +350,14 @@ export const prebuiltRuleAllowlistFields: AllowlistFields = { original_file_name: true, }, }, + github: { + org: true, + team: true, + repo: true, + category: true, + permission: true, + repository_public: true, + }, // Google/GCP google_workspace: { actor: { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts index a83326334c9d..223e732f946e 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts @@ -37,15 +37,10 @@ describe('diagnostics telemetry task test', () => { mockTelemetryEventsSender, testTaskExecutionPeriod ); - expect(mockTelemetryReceiver.fetchDiagnosticAlerts).toHaveBeenCalledWith( testTaskExecutionPeriod.last, testTaskExecutionPeriod.current ); - - expect(mockTelemetryEventsSender.queueTelemetryEvents).toHaveBeenCalledWith( - testDiagnosticsAlerts.hits.hits.flatMap((doc) => [doc._source]) - ); - expect(mockTelemetryEventsSender.sendOnDemand).toBeCalledTimes(1); + expect(mockTelemetryEventsSender.sendOnDemand).toBeCalledTimes(2); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts index 5c4604289eb5..290c5cfc44a6 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts @@ -11,7 +11,7 @@ import type { ITelemetryEventsSender } from '../sender'; import type { TelemetryEvent } from '../types'; import type { ITelemetryReceiver } from '../receiver'; import type { TaskExecutionPeriod } from '../task'; -import { TASK_METRICS_CHANNEL } from '../constants'; +import { TELEMETRY_CHANNEL_ENDPOINT_ALERTS, TASK_METRICS_CHANNEL } from '../constants'; export function createTelemetryDiagnosticsTaskConfig() { return { @@ -49,14 +49,15 @@ export function createTelemetryDiagnosticsTaskConfig() { return 0; } tlog(logger, `Received ${hits.length} diagnostic alerts`); - const diagAlerts: TelemetryEvent[] = hits.flatMap((h) => + const alerts: TelemetryEvent[] = hits.flatMap((h) => h._source != null ? [h._source] : [] ); - sender.queueTelemetryEvents(diagAlerts); + + await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_ALERTS, alerts); await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ createTaskMetric(taskName, true, startTime), ]); - return diagAlerts.length; + return alerts.length; } catch (err) { await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ createTaskMetric(taskName, false, startTime, err.message), diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index 4d2b16e355c6..4b762590b227 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -170,7 +170,6 @@ "@kbn/security-solution-features", "@kbn/content-management-plugin", "@kbn/discover-utils", - "@kbn/subscription-tracking", "@kbn/core-application-common", "@kbn/openapi-generator", "@kbn/es", @@ -178,6 +177,6 @@ "@kbn/unified-doc-viewer-plugin", "@kbn/shared-ux-error-boundary", "@kbn/zod-helpers", - "@kbn/core-http-common", + "@kbn/core-http-common" ] } diff --git a/x-pack/plugins/security_solution_ess/public/plugin.ts b/x-pack/plugins/security_solution_ess/public/plugin.ts index 7857c0ffa553..68b902a95dc8 100644 --- a/x-pack/plugins/security_solution_ess/public/plugin.ts +++ b/x-pack/plugins/security_solution_ess/public/plugin.ts @@ -45,7 +45,7 @@ export class SecuritySolutionEssPlugin }); securitySolution.setComponents({ - getStarted: getSecurityGetStartedComponent(services), + GetStarted: getSecurityGetStartedComponent(services), }); subscribeBreadcrumbs(services); diff --git a/x-pack/plugins/security_solution_serverless/public/plugin.ts b/x-pack/plugins/security_solution_serverless/public/plugin.ts index e7e58c42bcaa..77fcbc19d6e2 100644 --- a/x-pack/plugins/security_solution_serverless/public/plugin.ts +++ b/x-pack/plugins/security_solution_serverless/public/plugin.ts @@ -69,8 +69,8 @@ export class SecuritySolutionServerlessPlugin registerUpsellings(securitySolution.getUpselling(), productTypes, services); securitySolution.setComponents({ - getStarted: getSecurityGetStartedComponent(services, productTypes), - dashboardsLandingCallout: getDashboardsLandingCallout(services), + GetStarted: getSecurityGetStartedComponent(services, productTypes), + DashboardsLandingCallout: getDashboardsLandingCallout(services), }); startNavigation(services); diff --git a/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metering_task.ts b/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metering_task.ts index 1a9501424ba0..0dde94b40987 100644 --- a/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metering_task.ts +++ b/x-pack/plugins/security_solution_serverless/server/cloud_security/cloud_security_metering_task.ts @@ -205,14 +205,17 @@ const indexHasDataInDateRange = async ( cloudSecuritySolution: CloudSecuritySolutions, searchFrom: Date ) => { - const response = await esClient.search({ - index: METERING_CONFIGS[cloudSecuritySolution].index, - size: 1, - _source: false, - query: getSearchQueryByCloudSecuritySolution(cloudSecuritySolution, searchFrom), - }); + const response = await esClient.search( + { + index: METERING_CONFIGS[cloudSecuritySolution].index, + size: 1, + _source: false, + query: getSearchQueryByCloudSecuritySolution(cloudSecuritySolution, searchFrom), + }, + { ignore: [404] } + ); - return response.hits.hits.length > 0; + return response.hits?.hits.length > 0; }; const getSearchStartDate = (lastSuccessfulReport: Date): Date => { diff --git a/x-pack/plugins/serverless_search/public/application/components/api_key/basic_setup_form.tsx b/x-pack/plugins/serverless_search/public/application/components/api_key/basic_setup_form.tsx index a130e08654bc..c6ec0469168f 100644 --- a/x-pack/plugins/serverless_search/public/application/components/api_key/basic_setup_form.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/api_key/basic_setup_form.tsx @@ -72,7 +72,13 @@ export const BasicSetupForm: React.FC = ({ defaultMessage: 'User', })} > - {}} /> + {}} + /> = ({ }) => { return (
    - + {i18n.translate('xpack.serverlessSearch.apiKey.metadataLinkLabel', { defaultMessage: 'Learn how to structure role metadata', })} diff --git a/x-pack/plugins/serverless_search/public/application/components/api_key/security_privileges_form.tsx b/x-pack/plugins/serverless_search/public/application/components/api_key/security_privileges_form.tsx index a92224b2b45d..aefc7971d0a4 100644 --- a/x-pack/plugins/serverless_search/public/application/components/api_key/security_privileges_form.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/api_key/security_privileges_form.tsx @@ -24,7 +24,11 @@ export const SecurityPrivilegesForm: React.FC = ({ }) => { return (
    - + {i18n.translate('xpack.serverlessSearch.apiKey.roleDescriptorsLinkLabel', { defaultMessage: 'Learn how to structure role descriptors', })} diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/api_key_panel.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/api_key_panel.tsx index dd42310a05cd..eb1f4aba2ec2 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/api_key_panel.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/api_key_panel.tsx @@ -58,6 +58,7 @@ export const ApiKeyPanel: React.FC = ({ connector }) => { = ({ connecto = ({ connecto = ( - + {i18n.translate('xpack.serverlessSearch.connectors.runWithDockerLink', { defaultMessage: 'Run with Docker', })} @@ -73,6 +79,7 @@ export const ConnectorLinkElasticsearch: React.FC

    - {i18n.translate('xpack.serverlessSearch.connectors.variablesTitle', { - defaultMessage: 'Variables for your ', - })} - elastic/connectors/config.yml + elastic/connectors/config.yml }} + />

    diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/connector_overview.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/connector_overview.tsx index adf652316773..d141ae51c25c 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/connector_overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/connector_config/connector_overview.tsx @@ -71,6 +71,7 @@ export const ConnectorOverview: React.FC = ({ connector { name: nameLabel, render: (name: string, connector: Connector) => ( navigateToUrl(generatePath(EDIT_CONNECTOR_PATH, { id: connector.id }))} > {name || connector.id} @@ -235,6 +236,7 @@ export const ConnectorsTable: React.FC = () => {
    setFilter(e.currentTarget.value as Filter)} options={filterOptions} /> @@ -294,6 +296,7 @@ const DeleteConnectorModalAction: React.FC<{ connector: Connector }> = ({ connec )} setModalIsOpen(true)} iconType="trash" diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/delete_connector_modal.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/delete_connector_modal.tsx index 7e9ebb631fc4..a2e4b96176dc 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/delete_connector_modal.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/delete_connector_modal.tsx @@ -97,6 +97,7 @@ export const DeleteConnectorModal: React.FC = ({ )} > setInputConnectorName(e.target.value)} value={inputConnectorName} /> diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_connector.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_connector.tsx index f979f7dff283..78d47421420e 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_connector.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_connector.tsx @@ -72,7 +72,12 @@ export const EditConnector: React.FC = () => { } actions={ - navigateToUrl(`./`)}> + navigateToUrl(`./`)} + > {i18n.translate('xpack.serverlessSearch.connectors.goBack', { defaultMessage: 'Go back', })} @@ -107,6 +112,7 @@ export const EditConnector: React.FC = () => { id={'connectorMenu'} button={ = ({ connector }) = defaultMessage: 'Description', })} labelAppend={ - setIsEditing(true)}> + setIsEditing(true)} + > {EDIT_LABEL} } > {isEditing ? ( setNewDescription(event.target.value)} value={newDescription || ''} /> @@ -102,6 +107,7 @@ export const EditDescription: React.FC = ({ connector }) = `} > mutate(newDescription)} @@ -119,6 +125,7 @@ export const EditDescription: React.FC = ({ connector }) = `} > { diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_name.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_name.tsx index bba3dbec5376..e8073796c7c9 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/edit_name.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/edit_name.tsx @@ -80,6 +80,7 @@ export const EditName: React.FC = ({ connector }) => { `} > = ({ connector }) => { defaultMessage: 'Name', })} - setNewName(event.target.value)} value={newName} /> + setNewName(event.target.value)} + value={newName} + /> @@ -108,6 +113,7 @@ export const EditName: React.FC = ({ connector }) => { `} > = ({ connector }) => { `} > { diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx index a997c8086225..abb0ad64242d 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors/empty_connectors_prompt.tsx @@ -90,7 +90,10 @@ export const EmptyConnectorsPrompt: React.FC = () => { defaultMessage="Deploy connector code on your own infrastructure by running from {source}, or using {docker}" values={{ source: ( - + {i18n.translate( 'xpack.serverlessSearch.connectorsEmpty.sourceLabel', { defaultMessage: 'source' } @@ -98,7 +101,10 @@ export const EmptyConnectorsPrompt: React.FC = () => { ), docker: ( - + {i18n.translate( 'xpack.serverlessSearch.connectorsEmpty.dockerLabel', { defaultMessage: 'Docker' } @@ -157,7 +163,11 @@ export const EmptyConnectorsPrompt: React.FC = () => {
    - + {i18n.translate('xpack.serverlessSearch.connectorsEmpty.createConnector', { defaultMessage: 'Create connector', })} diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors_ingestion.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors_ingestion.tsx new file mode 100644 index 000000000000..ede574abba12 --- /dev/null +++ b/x-pack/plugins/serverless_search/public/application/components/connectors_ingestion.tsx @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiFlexGroup, + EuiFlexItem, + EuiTitle, + EuiSpacer, + EuiText, + EuiLink, + EuiIcon, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { GithubLink } from '@kbn/search-api-panels'; + +import React from 'react'; +import { useCreateConnector } from '../hooks/api/use_create_connector'; + +export const ConnectorIngestionPanel: React.FC<{ assetBasePath: string }> = ({ assetBasePath }) => { + const { createConnector } = useCreateConnector(); + return ( + + + +
    + {i18n.translate( + 'xpack.serverlessSearch.ingestData.alternativeOptions.connectorsTitle', + { + defaultMessage: 'Connectors', + } + )} +
    +
    + + +

    + {i18n.translate( + 'xpack.serverlessSearch.ingestData.alternativeOptions.connectorsDescription', + { + defaultMessage: + 'Sync third-party data sources to Elasticsearch, by deploying open code Elastic connectors on your own infrastructure. ', + } + )} +

    +
    +
    + + + createConnector()} + > + {i18n.translate( + 'xpack.serverlessSearch.ingestData.alternativeOptions.setupConnectorLabel', + { + defaultMessage: 'Set up a connector', + } + )} + + + + + + + + + + + + + + {i18n.translate( + 'xpack.serverlessSearch.ingestData.alternativeOptions.connectorDockerLabel', + { + defaultMessage: 'Docker', + } + )} + + + + + + + +
    + ); +}; diff --git a/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx b/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx index ebd7afc288d2..fd774f3dd491 100644 --- a/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/connectors_overview.tsx @@ -56,7 +56,11 @@ export const ConnectorsOverview = () => {
    - + {i18n.translate('xpack.serverlessSearch.connectorsPythonLink', { defaultMessage: 'elastic/connectors', })} @@ -67,6 +71,7 @@ export const ConnectorsOverview = () => { { defaultMessage="Sync third-party data sources to Elasticsearch, by deploying Elastic connectors on your own infrastructure. {learnMoreLink}" values={{ learnMoreLink: ( - + {LEARN_MORE_LABEL} ), diff --git a/x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx b/x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx index fc1699beffa8..9949b40e3c63 100644 --- a/x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/index_mappings_docs_link.tsx @@ -51,7 +51,12 @@ const IndexMappingsDocsLink: FunctionComponent<{ docLinks: CoreStart['docLinks']

    - + `using System; using Elastic.Clients.Elasticsearch.Serverless; -using Elastic.Clients.Elasticsearch.QueryDsl; +using Elastic.Clients.Elasticsearch.Serverless.QueryDsl; var client = new ElasticsearchClient("${cloudId}", new ApiKey("${apiKey}"));`, testConnection: `var info = await client.InfoAsync();`, diff --git a/x-pack/plugins/serverless_search/public/application/components/overview.tsx b/x-pack/plugins/serverless_search/public/application/components/overview.tsx index cb32a66cea20..6b5c6a1b4b4b 100644 --- a/x-pack/plugins/serverless_search/public/application/components/overview.tsx +++ b/x-pack/plugins/serverless_search/public/application/components/overview.tsx @@ -52,6 +52,7 @@ import { LanguageGrid } from './languages/language_grid'; import './overview.scss'; import { ApiKeyPanel } from './api_key/api_key'; import { ConnectorsCallout } from './connectors_callout'; +import { ConnectorIngestionPanel } from './connectors_ingestion'; export const ElasticsearchOverview = () => { const [selectedLanguage, setSelectedLanguage] = useState(javaDefinition); @@ -302,6 +303,7 @@ export const ElasticsearchOverview = () => { docLinks={docLinks} application={application} sharePlugin={share} + additionalIngestionPanel={} /> { {cloud.usersAndRolesUrl && ( - + {i18n.translate('xpack.serverlessSearch.overview.footer.links.inviteUsers', { defaultMessage: 'Invite more users', })} @@ -452,14 +458,22 @@ const OverviewFooter = () => { )} - + {i18n.translate('xpack.serverlessSearch.overview.footer.links.community', { defaultMessage: 'Join our community', })} - + {i18n.translate('xpack.serverlessSearch.overview.footer.links.feedback', { defaultMessage: 'Give feedback', })} diff --git a/x-pack/plugins/session_view/server/routes/alerts_client_mock.test.ts b/x-pack/plugins/session_view/server/routes/alerts_client_mock.test.ts index 10f1c48977c3..ff7631477602 100644 --- a/x-pack/plugins/session_view/server/routes/alerts_client_mock.test.ts +++ b/x-pack/plugins/session_view/server/routes/alerts_client_mock.test.ts @@ -65,6 +65,7 @@ const alertsClientParams: jest.Mocked = { ruleDataService: ruleDataServiceMock.create(), esClient: esClientMock, getRuleType: jest.fn(), + getRuleList: jest.fn(), getAlertIndicesAlias: getAlertIndicesAliasMock, }; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts index 708e8cd4e036..0eeb309dd225 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.test.ts @@ -5,13 +5,10 @@ * 2.0. */ import aws from 'aws4'; -import { Transform } from 'stream'; +import { PassThrough, Transform } from 'stream'; import { BedrockConnector } from './bedrock'; -import { waitFor } from '@testing-library/react'; import { actionsConfigMock } from '@kbn/actions-plugin/server/actions_config.mock'; import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; -import { EventStreamCodec } from '@smithy/eventstream-codec'; -import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { RunActionResponseSchema, StreamingResponseSchema } from '../../../common/bedrock/schema'; import { @@ -105,7 +102,7 @@ describe('BedrockConnector', () => { let stream; beforeEach(() => { stream = createStreamMock(); - stream.write(encodeBedrockResponse(mockResponseString)); + stream.write(new Uint8Array([1, 2, 3])); mockRequest = jest.fn().mockResolvedValue({ ...mockResponse, data: stream.transform }); // @ts-ignore connector.request = mockRequest; @@ -199,16 +196,9 @@ describe('BedrockConnector', () => { }); }); - it('transforms the response into a string', async () => { + it('responds with a readable stream', async () => { const response = await connector.invokeStream(aiAssistantBody); - - let responseBody: string = ''; - response.on('data', (data: string) => { - responseBody += data.toString(); - }); - await waitFor(() => { - expect(responseBody).toEqual(mockResponseString); - }); + expect(response instanceof PassThrough).toEqual(true); }); it('errors during API calls are properly handled', async () => { @@ -364,16 +354,3 @@ function createStreamMock() { }, }; } - -function encodeBedrockResponse(completion: string) { - return new EventStreamCodec(toUtf8, fromUtf8).encode({ - headers: {}, - body: Uint8Array.from( - Buffer.from( - JSON.stringify({ - bytes: Buffer.from(JSON.stringify({ completion })).toString('base64'), - }) - ) - ), - }); -} diff --git a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts index 70f8e121e151..ade589e54dc1 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/bedrock/bedrock.ts @@ -9,9 +9,7 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import aws from 'aws4'; import type { AxiosError } from 'axios'; import { IncomingMessage } from 'http'; -import { PassThrough, Transform } from 'stream'; -import { EventStreamCodec } from '@smithy/eventstream-codec'; -import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; +import { PassThrough } from 'stream'; import { RunActionParamsSchema, RunActionResponseSchema, @@ -178,12 +176,12 @@ export class BedrockConnector extends SubActionConnector { * @param messages An array of messages to be sent to the API * @param model Optional model to be used for the API request. If not provided, the default model from the connector will be used. */ - public async invokeStream({ messages, model }: InvokeAIActionParams): Promise { + public async invokeStream({ messages, model }: InvokeAIActionParams): Promise { const res = (await this.streamApi({ body: JSON.stringify(formatBedrockBody({ messages })), model, })) as unknown as IncomingMessage; - return res.pipe(transformToString()); + return res; } /** @@ -222,25 +220,3 @@ const formatBedrockBody = ({ stop_sequences: ['\n\nHuman:'], }; }; - -/** - * Takes in a readable stream of data and returns a Transform stream that - * uses the AWS proprietary codec to parse the proprietary bedrock response into - * a string of the response text alone, returning the response string to the stream - */ -const transformToString = () => - new Transform({ - transform(chunk, encoding, callback) { - const encoder = new TextEncoder(); - const decoder = new EventStreamCodec(toUtf8, fromUtf8); - const event = decoder.decode(chunk); - const body = JSON.parse( - Buffer.from( - JSON.parse(new TextDecoder('utf-8').decode(event.body)).bytes, - 'base64' - ).toString() - ); - const newChunk = encoder.encode(body.completion); - callback(null, newChunk); - }, - }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts index 7769dd8592fa..c7d6feb6887a 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.test.ts @@ -17,8 +17,7 @@ import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { actionsMock } from '@kbn/actions-plugin/server/mocks'; import { RunActionResponseSchema, StreamingResponseSchema } from '../../../common/openai/schema'; import { initDashboard } from './create_dashboard'; -import { Transform } from 'stream'; -import { waitFor } from '@testing-library/react'; +import { PassThrough, Transform } from 'stream'; jest.mock('./create_dashboard'); describe('OpenAIConnector', () => { @@ -315,53 +314,11 @@ describe('OpenAIConnector', () => { await expect(connector.invokeStream(sampleOpenAiBody)).rejects.toThrow('API Error'); }); - it('transforms the response into a string', async () => { + it('responds with a readable stream', async () => { // @ts-ignore connector.request = mockStream(); const response = await connector.invokeStream(sampleOpenAiBody); - - let responseBody: string = ''; - response.on('data', (data: string) => { - responseBody += data.toString(); - }); - await waitFor(() => { - expect(responseBody).toEqual('My new'); - }); - }); - it('correctly buffers stream of json lines', async () => { - const chunk1 = `data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"My"}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" new"}}]}`; - const chunk2 = `\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" message"}}]}\ndata: [DONE]`; - - // @ts-ignore - connector.request = mockStream([chunk1, chunk2]); - - const response = await connector.invokeStream(sampleOpenAiBody); - - let responseBody: string = ''; - response.on('data', (data: string) => { - responseBody += data.toString(); - }); - await waitFor(() => { - expect(responseBody).toEqual('My new message'); - }); - }); - it('correctly buffers partial lines', async () => { - const chunk1 = `data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"My"}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" new"`; - - const chunk2 = `}}]}\ndata: {"object":"chat.completion.chunk","choices":[{"delta":{"content":" message"}}]}\ndata: [DONE]`; - - // @ts-ignore - connector.request = mockStream([chunk1, chunk2]); - - const response = await connector.invokeStream(sampleOpenAiBody); - - let responseBody: string = ''; - response.on('data', (data: string) => { - responseBody += data.toString(); - }); - await waitFor(() => { - expect(responseBody).toEqual('My new message'); - }); + expect(response instanceof PassThrough).toEqual(true); }); }); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts index 78fca4bd8419..8dfeac0be850 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/openai/openai.ts @@ -7,8 +7,8 @@ import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; import type { AxiosError } from 'axios'; -import { PassThrough, Transform } from 'stream'; import { IncomingMessage } from 'http'; +import { PassThrough } from 'stream'; import { RunActionParamsSchema, RunActionResponseSchema, @@ -198,13 +198,13 @@ export class OpenAIConnector extends SubActionConnector { * the response from the streamApi method and returns the response string alone. * @param body - the OpenAI Invoke request body */ - public async invokeStream(body: InvokeAIActionParams): Promise { + public async invokeStream(body: InvokeAIActionParams): Promise { const res = (await this.streamApi({ body: JSON.stringify(body), stream: true, })) as unknown as IncomingMessage; - return res.pipe(new PassThrough()).pipe(transformToString()); + return res.pipe(new PassThrough()); } /** @@ -229,44 +229,3 @@ export class OpenAIConnector extends SubActionConnector { }; } } - -/** - * Takes in a readable stream of data and returns a Transform stream that - * parses the proprietary OpenAI response into a string of the response text alone, - * returning the response string to the stream - */ -const transformToString = () => { - let lineBuffer: string = ''; - const decoder = new TextDecoder(); - - return new Transform({ - transform(chunk, encoding, callback) { - const chunks = decoder.decode(chunk); - const lines = chunks.split('\n'); - lines[0] = lineBuffer + lines[0]; - lineBuffer = lines.pop() || ''; - callback(null, getNextChunk(lines)); - }, - flush(callback) { - // Emit an additional chunk with the content of lineBuffer if it has length - if (lineBuffer.length > 0) { - callback(null, getNextChunk([lineBuffer])); - } else { - callback(); - } - }, - }); -}; - -const getNextChunk = (lines: string[]) => { - const encoder = new TextEncoder(); - const nextChunk = lines - .map((str) => str.substring(6)) - .filter((str) => !!str && str !== '[DONE]') - .map((line) => { - const openaiResponse = JSON.parse(line); - return openaiResponse.choices[0]?.delta.content ?? ''; - }) - .join(''); - return encoder.encode(nextChunk); -}; diff --git a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts index 1602a7d29f12..fd37aa678ce6 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/synthetics_service.ts @@ -423,49 +423,48 @@ export class SyntheticsService { }; for await (const result of finder.find()) { - if (result.saved_objects.length === 0) { - return; - } - try { - if (!output) { - output = await this.getOutput(); + if (result.saved_objects.length > 0) { + try { if (!output) { - sendErrorTelemetryEvents(service.logger, service.server.telemetry, { - reason: 'API key is not valid.', - message: 'Failed to push configs. API key is not valid.', - type: 'invalidApiKey', - stackVersion: service.server.stackVersion, - }); - return; + output = await this.getOutput(); + if (!output) { + sendErrorTelemetryEvents(service.logger, service.server.telemetry, { + reason: 'API key is not valid.', + message: 'Failed to push configs. API key is not valid.', + type: 'invalidApiKey', + stackVersion: service.server.stackVersion, + }); + return; + } } - } - const monitors = result.saved_objects.filter(({ error }) => !error); - const formattedConfigs = this.normalizeConfigs(monitors, paramsBySpace); + const monitors = result.saved_objects.filter(({ error }) => !error); + const formattedConfigs = this.normalizeConfigs(monitors, paramsBySpace); - this.logger.debug( - `${formattedConfigs.length} monitors will be pushed to synthetics service.` - ); + this.logger.debug( + `${formattedConfigs.length} monitors will be pushed to synthetics service.` + ); - formattedConfigs.forEach((monitor) => { - monitor.locations.forEach((location) => { - if (location.isServiceManaged) { - bucketsByLocation[location.id]?.push(monitor); - } + formattedConfigs.forEach((monitor) => { + monitor.locations.forEach((location) => { + if (location.isServiceManaged) { + bucketsByLocation[location.id]?.push(monitor); + } + }); }); - }); - await syncAllLocations(PER_PAGE); - } catch (e) { - sendErrorTelemetryEvents(service.logger, service.server.telemetry, { - reason: 'Failed to push configs to service', - message: e?.message, - type: 'pushConfigsError', - code: e?.code, - status: e.status, - stackVersion: service.server.stackVersion, - }); - this.logger.error(e); + await syncAllLocations(PER_PAGE); + } catch (e) { + sendErrorTelemetryEvents(service.logger, service.server.telemetry, { + reason: 'Failed to push configs to service', + message: e?.message, + type: 'pushConfigsError', + code: e?.code, + status: e.status, + stackVersion: service.server.stackVersion, + }); + this.logger.error(e); + } } } diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts index 63f58acf9948..a6ce796d4f3f 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/block_list.cy.ts @@ -35,7 +35,8 @@ const FIRST_BLOCK_LIST_NEW_DESCRIPTION = 'the first description'; const SECOND_BLOCK_LIST_NEW_NAME = 'second blocklist entry'; const SECOND_BLOCK_LIST_NEW_DESCRIPTION = 'the second description'; -describe('Block list with invalid indicators', { tags: '@ess' }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/171783 +describe.skip('Block list with invalid indicators', { tags: '@ess' }, () => { beforeEach(() => { esArchiverLoad('threat_intelligence/invalid_indicators_data'); login(); diff --git a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts index cbb95e9a610f..6ad05c047257 100644 --- a/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts +++ b/x-pack/plugins/threat_intelligence/cypress/e2e/indicators.cy.ts @@ -56,7 +56,11 @@ const THREAT_INTELLIGENCE = '/app/security/threat_intelligence/indicators'; const URL_WITH_CONTRADICTORY_FILTERS = '/app/security/threat_intelligence/indicators?indicators=(filterQuery:(language:kuery,query:%27%27),filters:!((%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:%27%27,key:threat.indicator.type,negate:!f,params:(query:file),type:phrase),query:(match_phrase:(threat.indicator.type:file))),(%27$state%27:(store:appState),meta:(alias:!n,disabled:!f,index:%27%27,key:threat.indicator.type,negate:!f,params:(query:url),type:phrase),query:(match_phrase:(threat.indicator.type:url)))),timeRange:(from:now/d,to:now/d))'; -describe('Invalid Indicators', { tags: '@ess' }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/171779 +// FLAKY: https://github.com/elastic/kibana/issues/171778 +// FLAKY: https://github.com/elastic/kibana/issues/171785 +// FLAKY: https://github.com/elastic/kibana/issues/171786 +describe.skip('Invalid Indicators', { tags: '@ess' }, () => { describe('verify the grid loads even with missing fields', () => { beforeEach(() => { esArchiverLoad('threat_intelligence/invalid_indicators_data'); @@ -132,7 +136,9 @@ describe('Invalid Indicators', { tags: '@ess' }, () => { }); }); -describe('Indicators', () => { +// FLAKY: https://github.com/elastic/kibana/issues/171781 +// FLAKY: https://github.com/elastic/kibana/issues/171780 +describe.skip('Indicators', () => { before(() => { esArchiverLoad('threat_intelligence/indicators_data'); }); diff --git a/x-pack/plugins/threat_intelligence/public/components/paywall.tsx b/x-pack/plugins/threat_intelligence/public/components/paywall.tsx index a01ca32a0694..8a010550e8a6 100644 --- a/x-pack/plugins/threat_intelligence/public/components/paywall.tsx +++ b/x-pack/plugins/threat_intelligence/public/components/paywall.tsx @@ -6,17 +6,21 @@ */ import React, { VFC } from 'react'; -import { EuiButton, EuiEmptyPrompt, EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; +import { + EuiButton, + EuiButtonEmpty, + EuiEmptyPrompt, + EuiFlexGroup, + EuiFlexItem, + EuiIcon, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { SubscriptionButtonEmpty } from '@kbn/subscription-tracking'; -import type { SubscriptionContextData } from '@kbn/subscription-tracking'; - -const subscriptionContext: SubscriptionContextData = { - feature: 'threat-intelligence', - source: 'security__threat-intelligence', -}; +import { useKibana } from '../hooks/use_kibana'; export const Paywall: VFC = () => { + const { + services: { application }, + } = useKibana(); return ( } @@ -52,12 +56,18 @@ export const Paywall: VFC = () => {
    - + + application.navigateToApp('management', { + path: 'stack/license_management/home', + }) + } + > - +
    diff --git a/x-pack/plugins/threat_intelligence/public/mocks/story_providers.tsx b/x-pack/plugins/threat_intelligence/public/mocks/story_providers.tsx index d13c3f561e74..249a9d05afbc 100644 --- a/x-pack/plugins/threat_intelligence/public/mocks/story_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/mocks/story_providers.tsx @@ -12,7 +12,6 @@ import { CoreStart, IUiSettingsClient } from '@kbn/core/public'; import { TimelinesUIStart } from '@kbn/timelines-plugin/public'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; -import { MockSubscriptionTrackingProvider } from '@kbn/subscription-tracking/mocks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; import { mockIndicatorsFiltersContext } from './mock_indicators_filters_context'; @@ -108,9 +107,7 @@ export const StoryProvidersComponent: VFC = ({ - - {children} - + {children} diff --git a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx index 12c42052ee26..37360284b6aa 100644 --- a/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/mocks/test_providers.tsx @@ -17,7 +17,6 @@ import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks import { createTGridMocks } from '@kbn/timelines-plugin/public/mock'; import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; -import { MockSubscriptionTrackingProvider } from '@kbn/subscription-tracking/mocks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { MemoryRouter } from 'react-router-dom'; import { casesPluginMock } from '@kbn/cases-plugin/public/mocks'; @@ -142,13 +141,11 @@ export const TestProvidersComponent: FC = ({ children }) => ( - - - - {children} - - - + + + {children} + + diff --git a/x-pack/plugins/threat_intelligence/public/plugin.tsx b/x-pack/plugins/threat_intelligence/public/plugin.tsx index e30e9f92c0a5..49f6b3b7724b 100755 --- a/x-pack/plugins/threat_intelligence/public/plugin.tsx +++ b/x-pack/plugins/threat_intelligence/public/plugin.tsx @@ -11,7 +11,6 @@ import { Provider as ReduxStoreProvider } from 'react-redux'; import React, { Suspense } from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { ExternalReferenceAttachmentType } from '@kbn/cases-plugin/public/client/attachment_framework/types'; -import { SubscriptionTrackingProvider } from '@kbn/subscription-tracking'; import { generateAttachmentType } from './modules/cases/utils/attachments'; import { KibanaContextProvider } from './hooks/use_kibana'; import { @@ -44,16 +43,11 @@ export const createApp = - - - }> - - - - + + }> + + + diff --git a/x-pack/plugins/threat_intelligence/tsconfig.json b/x-pack/plugins/threat_intelligence/tsconfig.json index 661186c943b5..2e390483ab22 100644 --- a/x-pack/plugins/threat_intelligence/tsconfig.json +++ b/x-pack/plugins/threat_intelligence/tsconfig.json @@ -32,8 +32,7 @@ "@kbn/utility-types", "@kbn/ui-theme", "@kbn/securitysolution-io-ts-list-types", - "@kbn/core-ui-settings-browser", - "@kbn/subscription-tracking" + "@kbn/core-ui-settings-browser" ], "exclude": ["target/**/*"] } diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts index 471146f583dc..61403df03509 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts @@ -17,7 +17,7 @@ import { getFieldType, getDataGridSchemaFromKibanaFieldType, getDataGridSchemaFromESFieldType, - getFieldsFromKibanaIndexPattern, + getFieldsFromKibanaDataView, showDataGridColumnChartErrorMessageToast, useDataGrid, useRenderCellValue, @@ -140,7 +140,7 @@ export const useIndexData = ( allPopulatedFields = [...new Set(docs.map(Object.keys).flat(1))]; } - const allDataViewFields = getFieldsFromKibanaIndexPattern(dataView); + const allDataViewFields = getFieldsFromKibanaDataView(dataView); return allPopulatedFields.filter((d) => allDataViewFields.includes(d)).sort(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [dataViewFieldsData, populatedFields]); diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 62c016c9b67e..7d306653dfeb 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -5308,7 +5308,6 @@ "savedSearch.kibana_context.savedSearchId.help": "Spécifier l'ID de recherche enregistrée à utiliser pour les requêtes et les filtres", "savedSearch.kibana_context.timeRange.help": "Spécifier le filtre de plage temporelle Kibana", "searchApiPanels.welcomeBanner.header.greeting.customTitle": "Bonjour {name} !", - "searchApiPanels.welcomeBanner.ingestData.clientDocLink": "Référence d’API {languageName}", "searchApiPanels.welcomeBanner.installClient.clientDocLink": "Documentation du client {languageName}", "searchApiPanels.welcomeBanner.selectClient.description": "Elastic construit et assure la maintenance des clients dans plusieurs langues populaires et notre communauté a contribué à beaucoup d'autres. Sélectionnez votre client linguistique favori or explorez la {console} pour commencer.", "searchApiPanels.welcomeBanner.codeBox.copyButtonLabel": "Copier", @@ -5316,22 +5315,7 @@ "searchApiPanels.welcomeBanner.header.description": "Configurez votre client de langage de programmation, ingérez des données, et vous serez prêt à commencer vos recherches en quelques minutes.", "searchApiPanels.welcomeBanner.header.greeting.defaultTitle": "Bonjour !", "searchApiPanels.welcomeBanner.header.title": "Lancez-vous avec Elasticsearch", - "searchApiPanels.welcomeBanner.ingestData.beatsDescription": "Des agents légers conçus pour le transfert de données pour Elasticsearch. Utilisez Beats pour envoyer des données opérationnelles depuis vos serveurs.", - "searchApiPanels.welcomeBanner.ingestData.beatsLink": "Beats", - "searchApiPanels.welcomeBanner.ingestData.beatsTitle": "Beats", - "searchApiPanels.welcomeBanner.ingestData.connectorsDescription": "Des intégrations spécialisées pour synchroniser des données de sources tierces avec Elasticsearch. Utilisez des connecteurs Elastic pour synchroniser du contenu d’une plage de bases de données et de stockage d’objets.", - "searchApiPanels.welcomeBanner.ingestData.connectorsPythonLink": "connecteurs-python", - "searchApiPanels.welcomeBanner.ingestData.connectorsTitle": "Client de connecteur", "searchApiPanels.welcomeBanner.ingestData.description": "Ajoutez des données à votre flux de données ou à votre index pour les rendre interrogeables. Choisissez une méthode d’ingestion qui correspond à votre application et à votre workflow.", - "searchApiPanels.welcomeBanner.ingestData.ingestApiDescription": "La façon la plus flexible d’indexer des données, ce qui vous donne un contrôle total sur vos options de personnalisation et d’optimisation.", - "searchApiPanels.welcomeBanner.ingestData.ingestApiLabel": "Ingérer via une API", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationDescription": "Des outils d’ingestion spécialisés optimisés pour transformer des données et les transférer à Elasticsearch.", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationLabel": "Ingérer via l’intégration", - "searchApiPanels.welcomeBanner.ingestData.ingestLegendLabel": "Sélectionner une méthode d'ingestion", - "searchApiPanels.welcomeBanner.ingestData.integrationsLink": "À propos des intégrations", - "searchApiPanels.welcomeBanner.ingestData.logstashDescription": "Ajoutez des données à votre flux de données ou à votre index pour les rendre interrogeables. Choisissez une méthode d’ingestion qui correspond à votre application et à votre workflow.", - "searchApiPanels.welcomeBanner.ingestData.logstashLink": "Logstash", - "searchApiPanels.welcomeBanner.ingestData.logstashTitle": "Logstash", "searchApiPanels.welcomeBanner.ingestData.title": "Ingérer des données", "searchApiPanels.welcomeBanner.installClient.description": "Elastic construit et assure la maintenance des clients dans plusieurs langues populaires et notre communauté a contribué à beaucoup d'autres. Installez votre client de langage favori pour commencer.", "searchApiPanels.welcomeBanner.installClient.title": "Installer un client", @@ -18636,9 +18620,7 @@ "xpack.grokDebugger.unknownErrorTitle": "Un problème est survenu", "xpack.idxMgmt.badgeAriaLabel": "{label}. Sélectionnez pour filtrer selon cet élément.", "xpack.idxMgmt.clearCacheIndicesAction.indexCacheClearedMessage": "Le cache de l'index {indexNames} a été effacé.", - "xpack.idxMgmt.clearCacheIndicesAction.successMessage": "Le cache a bien été effacé : [{indexNames}]", "xpack.idxMgmt.closeIndicesAction.indexClosedMessage": "L'index {indexNames} a été fermé.", - "xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage": "Fermeture réussie : [{indexNames}]", "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription": "{createLink} un modèle d'index ou {editLink}-en un existant.", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDescription": "Informations arbitraires sur le modèle stockées dans l'état du cluster. {learnMoreLink}", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaHelpText": "Utiliser le format JSON : {code}", @@ -18657,7 +18639,6 @@ "xpack.idxMgmt.deleteDataStreamsConfirmationModal.multipleErrorsNotificationMessageText": "Erreur lors de la suppression de {count} flux de données", "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, one {# flux de données} many {# flux de données} other {# flux de données}} supprimé", "xpack.idxMgmt.deleteIndicesAction.indexDeletedMessage": "L'index {indexNames} a été supprimé.", - "xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage": "Suppression réussie : [{indexNames}]", "xpack.idxMgmt.deleteTemplatesModal.confirmButtonLabel": "Supprimer {numTemplatesToDelete, plural, one {modèle} many {modèles} other {modèles}}", "xpack.idxMgmt.deleteTemplatesModal.deleteDescription": "Vous êtes sur le point de supprimer {numTemplatesToDelete, plural, one {ce modèle} many {ces modèles} other {ces modèles}} :", "xpack.idxMgmt.deleteTemplatesModal.modalTitleText": "Supprimer {numTemplatesToDelete, plural, one {modèle} many {# modèles} other {# modèles}}", @@ -18675,9 +18656,7 @@ "xpack.idxMgmt.enrichPolicyCreate.configurationStep.queryHelpText": "Valeur par défaut : requête {code}.", "xpack.idxMgmt.enrichPolicyCreate.configurationStep.rangeTypePopOver": "{type} correspond à un nombre, une date ou une plage d'adresses IP.", "xpack.idxMgmt.flushIndicesAction.indexFlushedMessage": "L'index {indexNames} a été vidé.", - "xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage": "Vidage effectué avec succès : [{indexNames}]", "xpack.idxMgmt.forceMergeIndicesAction.indexForcemergedMessage": "L'index {indexNames} a fait l'objet d'une fusion forcée.", - "xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage": "Fusion forcée effectué avec succès : [{indexNames}]", "xpack.idxMgmt.formWizard.stepAliases.aliasesEditorHelpText": "Utiliser le format JSON : {code}", "xpack.idxMgmt.formWizard.stepSettings.settingsEditorHelpText": "Utiliser le format JSON : {code}", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "Afficher {indexName} dans Discover", @@ -18774,9 +18753,7 @@ "xpack.idxMgmt.mappingsEditor.sourceFieldDescription": "Le champ _source contient le corps du document JSON d'origine qui a été fourni au moment de l'indexation. Vous pouvez nettoyer des champs individuels en définissant ceux à inclure ou exclure du champ _source. {docsLink}", "xpack.idxMgmt.mappingsEditor.typeField.documentationLinkLabel": "Documentation de {typeName}", "xpack.idxMgmt.openIndicesAction.indexOpenedMessage": "L'index {indexNames} a été ouvert.", - "xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage": "Ouverture réussie : [{indexNames}]", "xpack.idxMgmt.refreshIndicesAction.indexRefreshedMessage": "L'index {indexNames} a été actualisé.", - "xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage": "Actualisation réussie : [{indexNames}]", "xpack.idxMgmt.templateDetails.summaryTab.indexPatternsDescriptionListTitle": "{numIndexPatterns, plural, one {Modèle} many {Modèles d''indexation manquants} other {Modèles}} d'index", "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription": "Le modèle crée des flux de données au lieu d'index. {docsLink}", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsHelpText": "Les espaces et les caractères {invalidCharactersList} ne sont pas autorisés.", @@ -22348,7 +22325,6 @@ "xpack.lens.config.configFlyoutCallout": "ES|QL propose actuellement des options de configuration limitées", "xpack.lens.config.editLabel": "Modifier la configuration", "xpack.lens.config.editLinkLabel": "Modifier dans Lens", - "xpack.lens.config.editVisualizationLabel": "Modifier la visualisation", "xpack.lens.config.experimentalLabel": "Version d'évaluation technique", "xpack.lens.configPanel.addLayerButton": "Ajouter un calque", "xpack.lens.configPanel.experimentalLabel": "Version d'évaluation technique", @@ -25345,7 +25321,7 @@ "xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "Les vues de données utilisant la recherche inter-clusters ne sont pas prises en charge.", "xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "Erreur lors du chargement de la vue de données utilisée par la recherche enregistrée", "xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "Aucun recherche enregistrée ni aucun index correspondants n'ont été trouvés.", - "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "Vue de données", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "Vue de données", "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "Recherche enregistrée", "xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "Vous ne pourrez peut-être pas visualiser les résultats de la tâche si aucune vue de données n'est créée pour l'index de destination.", "xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "Les arbres de décision dépassant cette profondeur sont pénalisés dans les calculs de perte.", @@ -29234,7 +29210,6 @@ "xpack.observability.customThreshold.rule.alertFlyout.customEquationTooltip": "Ceci est compatible avec des calculs de base (A + B / C) et la logique booléenne (A < B ? A : B).", "xpack.observability.customThreshold.rule.alertFlyout.dataViewError.noTimestamp": "La vue de données sélectionnée ne dispose pas de champ d'horodatage. Veuillez sélectionner une autre vue de données.", "xpack.observability.customThreshold.rule.alertFlyout.defineTextQueryPrompt": "Définir le filtre de recherche (facultatif)", - "xpack.observability.customThreshold.rule.alertFlyout.error.aggregationRequired": "L'agrégation est requise.", "xpack.observability.customThreshold.rule.alertFlyout.error.equation.invalidCharacters": "Le champ d'équation prend en charge uniquement les caractères suivants : A-Z, +, -, /, *, (, ), ?, !, &, :, |, >, <, =", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidFilterQuery": "La requête de filtre n'est pas valide.", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidSearchConfiguration": "La vue de données est requise.", @@ -32358,12 +32333,7 @@ "xpack.securitySolution.responseActionsList.list.recordRange": "Affichage de {range} sur {total} {recordsLabel}", "xpack.securitySolution.responseActionsList.list.recordRangeLabel": "{records, plural, one {action de réponse} many {actions de réponse} other {actions de réponse}}", "xpack.securitySolution.riskInformation.howCalculatedText": "Le dispositif Entity Risk s'exécute toutes les heures afin de regrouper les alertes \"Open\" et \"Acknowledged\" des 30 derniers jours et attribue un score de risque à l'hôte ou à l'utilisateur. Il agrège ensuite les scores de risque individuels et les normalise dans une fourchette de 0 à 100 à l'aide de {riemannZetaLink} .", - "xpack.securitySolution.riskInformation.learnMore": "En savoir plus sur les risques {riskEntity}.", "xpack.securitySolution.riskInformation.riskHeader": "Plage de scores de risque de {riskEntity}", - "xpack.securitySolution.riskInformation.riskScoreFieldLabel": "Score de risque de {riskEntity}", - "xpack.securitySolution.riskInformation.riskScoreFieldText": "Le champ {riskScoreField} représente le risque normalisé du {riskEntity} sous la forme d'une valeur numérique unique. Vous pouvez utiliser cette valeur comme indicateur relatif du risque dans les playbooks de triage et de réponse.", - "xpack.securitySolution.riskInformation.riskScoreLevelLabel": "Niveau de risque {riskEntity}", - "xpack.securitySolution.riskInformation.riskScoreLevelText": "Le champ {riskLevelField} représente l'un des six niveaux de risque de {riskEntity}, sur la base d'indicateurs de risque prédéfinis.", "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "Impossible de supprimer {totalCount, plural, =1 {pipeline} one {pipelines} many {pipelines} other {pipelines}} d'ingestion", "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "Impossible de supprimer {totalCount, plural, =1 {Transformer} one {Transformations} many {Transformations} other {Transformations}}", "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "Impossible de démarrer {totalCount, plural, =1 {Transformer} one {Transformations} many {Transformations} other {Transformations}}", @@ -43480,7 +43450,6 @@ "unifiedDocViewer.sourceViewer.errorMessageTitle": "Une erreur s'est produite.", "unifiedDocViewer.sourceViewer.refresh": "Actualiser", "utils.filename.pathWarning": "Le chemin est peut-être incorrectement formé ; vérifiez la valeur", - "utils.filename.wildcardWarning": "l'utilisation de caractères génériques dans les chemins de fichier peut affecter les performances du point de terminaison", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.description": "Active la bibliothèque de graphiques héritée pour les graphiques de jauge dans Visualize.", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.name": "Bibliothèque de graphiques héritée pour les jauges", "visTypeGauge.controls.gaugeOptions.alignmentLabel": "Alignement", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c0a992ffcf2a..6666f7b6e0ee 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5323,7 +5323,6 @@ "savedSearch.kibana_context.savedSearchId.help": "クエリとフィルターに使用する保存検索ID を指定します。", "savedSearch.kibana_context.timeRange.help": "Kibana 時間範囲フィルターを指定します", "searchApiPanels.welcomeBanner.header.greeting.customTitle": "{name}様", - "searchApiPanels.welcomeBanner.ingestData.clientDocLink": "{languageName}APIリファレンス", "searchApiPanels.welcomeBanner.installClient.clientDocLink": "{languageName}クライアントドキュメント", "searchApiPanels.welcomeBanner.selectClient.description": "Elasticは複数の一般的な言語でクライアントを構築および保守します。Elasticのコミュニティはさらに多くを提供しています。お気に入りの言語クライアントを選択するか、{console}を起動して開始します。", "searchApiPanels.welcomeBanner.codeBox.copyButtonLabel": "コピー", @@ -5331,22 +5330,7 @@ "searchApiPanels.welcomeBanner.header.description": "プログラミング言語のクライアントを設定し、データを取り込めば、数分で検索を開始できます。", "searchApiPanels.welcomeBanner.header.greeting.defaultTitle": "こんにちは。", "searchApiPanels.welcomeBanner.header.title": "Elasticsearchをはじめよう", - "searchApiPanels.welcomeBanner.ingestData.beatsDescription": "Elasticsearch向けの軽量の、専用データ転送機能。Beatsを使用して、サーバーから運用データを送信します。", - "searchApiPanels.welcomeBanner.ingestData.beatsLink": "ビート", - "searchApiPanels.welcomeBanner.ingestData.beatsTitle": "ビート", - "searchApiPanels.welcomeBanner.ingestData.connectorsDescription": "サードパーティのソースからElasticsearchにデータを同期するための特別な統合。Elasticコネクターを使って、さまざまなデータベースやオブジェクトストアからコンテンツを同期できます。", - "searchApiPanels.welcomeBanner.ingestData.connectorsPythonLink": "connectors-python", - "searchApiPanels.welcomeBanner.ingestData.connectorsTitle": "コネクタークライアント", "searchApiPanels.welcomeBanner.ingestData.description": "データストリームやインデックスにデータを追加して、データを検索可能にします。アプリケーションとワークフローに合ったインジェスト方法を選択します。", - "searchApiPanels.welcomeBanner.ingestData.ingestApiDescription": "データをインデックス化する最も柔軟な方法で、カスタマイズや最適化オプションを完全に制御できます。", - "searchApiPanels.welcomeBanner.ingestData.ingestApiLabel": "API経由でインジェスト", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationDescription": "データを変換してElasticsearchに送信するために最適化された専用のインジェストツール。", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationLabel": "統合経由でインジェスト", - "searchApiPanels.welcomeBanner.ingestData.ingestLegendLabel": "インジェスチョン方法を選択", - "searchApiPanels.welcomeBanner.ingestData.integrationsLink": "統合について", - "searchApiPanels.welcomeBanner.ingestData.logstashDescription": "データストリームやインデックスにデータを追加して、データを検索可能にします。アプリケーションとワークフローに合ったインジェスト方法を選択します。", - "searchApiPanels.welcomeBanner.ingestData.logstashLink": "Logstash", - "searchApiPanels.welcomeBanner.ingestData.logstashTitle": "Logstash", "searchApiPanels.welcomeBanner.ingestData.title": "データをインジェスト", "searchApiPanels.welcomeBanner.installClient.description": "Elasticは複数の一般的な言語でクライアントを構築および保守します。Elasticのコミュニティはさらに多くを提供しています。開始するには、お気に入りの言語クライアントをインストールします。", "searchApiPanels.welcomeBanner.installClient.title": "クライアントをインスト-ル", @@ -18649,9 +18633,7 @@ "xpack.grokDebugger.unknownErrorTitle": "問題が発生しました", "xpack.idxMgmt.badgeAriaLabel": "{label}。選択すると、これをフィルタリングします。", "xpack.idxMgmt.clearCacheIndicesAction.indexCacheClearedMessage": "インデックス{indexNames}のキャッシュがクリアされました。", - "xpack.idxMgmt.clearCacheIndicesAction.successMessage": "キャッシュが削除されました:[{indexNames}]", "xpack.idxMgmt.closeIndicesAction.indexClosedMessage": "インデックス{indexNames}は閉じられました。", - "xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage": "[{indexNames}] がクローズされました", "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription": "インデックステンプレートを{createLink}するか、既存のテンプレートを{editLink}してください。", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDescription": "クラスター状態に格納された、テンプレートに関する任意の情報。{learnMoreLink}", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaHelpText": "JSONフォーマットを使用:{code}", @@ -18670,7 +18652,6 @@ "xpack.idxMgmt.deleteDataStreamsConfirmationModal.multipleErrorsNotificationMessageText": "{count}データストリームの削除エラー", "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteMultipleNotificationMessageText": "{numSuccesses, plural, other {#個のデータストリーム}}が削除されました", "xpack.idxMgmt.deleteIndicesAction.indexDeletedMessage": "インデックス{indexNames}が削除されました。", - "xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage": "[{indexNames}] が削除されました", "xpack.idxMgmt.deleteTemplatesModal.confirmButtonLabel": "{numTemplatesToDelete, plural, other {テンプレート}}削除", "xpack.idxMgmt.deleteTemplatesModal.deleteDescription": "{numTemplatesToDelete, plural, other {これらのテンプレート}}を削除しようとしています:", "xpack.idxMgmt.deleteTemplatesModal.modalTitleText": "{numTemplatesToDelete, plural, other {#個のテンプレート}}削除", @@ -18688,9 +18669,7 @@ "xpack.idxMgmt.enrichPolicyCreate.configurationStep.queryHelpText": "デフォルトは{code}クエリです。", "xpack.idxMgmt.enrichPolicyCreate.configurationStep.rangeTypePopOver": "{type}は、番号、日付、またはIPアドレスの範囲と一致します。", "xpack.idxMgmt.flushIndicesAction.indexFlushedMessage": "インデックス{indexNames}がフラッシュされました。", - "xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage": "[{indexNames}]がフラッシュされました", "xpack.idxMgmt.forceMergeIndicesAction.indexForcemergedMessage": "インデックス{indexNames}は強制的にマージされました。", - "xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage": "[{indexNames}]が強制結合されました", "xpack.idxMgmt.formWizard.stepAliases.aliasesEditorHelpText": "JSONフォーマットを使用:{code}", "xpack.idxMgmt.formWizard.stepSettings.settingsEditorHelpText": "JSONフォーマットを使用:{code}", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "Discoverで{indexName}を表示", @@ -18787,9 +18766,7 @@ "xpack.idxMgmt.mappingsEditor.sourceFieldDescription": "_source フィールドには、インデックスの時点で指定された元の JSON ドキュメント本文が含まれています。_sourceフィールドに含めるか除外するフィールドを定義することで、_sourceフィールドから個別のフィールドを削除することができます。{docsLink}", "xpack.idxMgmt.mappingsEditor.typeField.documentationLinkLabel": "{typeName} ドキュメント", "xpack.idxMgmt.openIndicesAction.indexOpenedMessage": "インデックス{indexNames}は開かれました。", - "xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage": "[{indexNames}] が開かれました", "xpack.idxMgmt.refreshIndicesAction.indexRefreshedMessage": "インデックス{indexNames}は更新されました。", - "xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage": "[{indexNames}] が更新されました", "xpack.idxMgmt.templateDetails.summaryTab.indexPatternsDescriptionListTitle": "インデックス{numIndexPatterns, plural, other {パターン}}", "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription": "テンプレートは、インデックスではなく、データストリームを作成します。{docsLink}", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsHelpText": "スペースと{invalidCharactersList}文字は使用できません。", @@ -22362,7 +22339,6 @@ "xpack.lens.config.configFlyoutCallout": "現在、ES|QLでは、構成オプションは限られています。", "xpack.lens.config.editLabel": "構成の編集", "xpack.lens.config.editLinkLabel": "Lensで編集", - "xpack.lens.config.editVisualizationLabel": "ビジュアライゼーションを編集", "xpack.lens.config.experimentalLabel": "テクニカルプレビュー", "xpack.lens.configPanel.addLayerButton": "レイヤーを追加", "xpack.lens.configPanel.experimentalLabel": "テクニカルプレビュー", @@ -25344,7 +25320,7 @@ "xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "クラスター横断検索を使用するデータビューはサポートされていません。", "xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "保存された検索で使用されているデータビューの読み込みエラー", "xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "一致インデックスまたは保存した検索が見つかりません。", - "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "データビュー", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "データビュー", "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "保存検索", "xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "デスティネーションインデックスのデータビューが作成されていない場合は、ジョブ結果を表示できないことがあります。", "xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "この深さを超える決定木は、損失計算でペナルティがあります。", @@ -29233,7 +29209,6 @@ "xpack.observability.customThreshold.rule.alertFlyout.customEquationTooltip": "これは基本的な数学ロジック(A + B / C)とブールロジック(A < B ?A :B)をサポートします。", "xpack.observability.customThreshold.rule.alertFlyout.dataViewError.noTimestamp": "選択したデータビューにタイムスタンプフィールドがありません。他のデータビューを選択してください。", "xpack.observability.customThreshold.rule.alertFlyout.defineTextQueryPrompt": "クエリフィルターを定義(任意)", - "xpack.observability.customThreshold.rule.alertFlyout.error.aggregationRequired": "集約が必要です。", "xpack.observability.customThreshold.rule.alertFlyout.error.equation.invalidCharacters": "等式フィールドでは次の文字のみを使用できます:A-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidFilterQuery": "フィルタークエリは無効です。", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidSearchConfiguration": "データビューが必要です。", @@ -32356,12 +32331,7 @@ "xpack.securitySolution.responseActionsList.list.recordRange": "{total} {recordsLabel}件中{range}を表示中", "xpack.securitySolution.responseActionsList.list.recordRangeLabel": "{records, plural, other {対応アクション}}", "xpack.securitySolution.riskInformation.howCalculatedText": "エンティティリスクエンジンは、過去30日間の\"オープン\"および\"確認済み\"アラートを集約し、ホストまたはユーザーにリスクスコアを割り当てるために1時間ごとに実行されます。次に、個々のリスクスコアを集約し、{riemannZetaLink}を使用して0~100の範囲に正規化します。", - "xpack.securitySolution.riskInformation.learnMore": "{riskEntity}リスクの詳細", "xpack.securitySolution.riskInformation.riskHeader": "{riskEntity}リスクスコア範囲", - "xpack.securitySolution.riskInformation.riskScoreFieldLabel": "{riskEntity}リスクスコア", - "xpack.securitySolution.riskInformation.riskScoreFieldText": "{riskScoreField}フィールドは{riskEntity}の正規化されたリスクを1つの数値として表します。この値は、トリアージとレスポンスのプレイブックでリスクの相対的な指標として使用できます。", - "xpack.securitySolution.riskInformation.riskScoreLevelLabel": "{riskEntity}リスクレベル", - "xpack.securitySolution.riskInformation.riskScoreLevelText": "{riskLevelField}フィールドは、定義済みのリスクメトリックに基づく{riskEntity}の6つのリスクレベルのうちの1つを表します。", "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "インジェスト{totalCount, plural, =1 {パイプライン} other {パイプライン}}を削除できませんでした", "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "{totalCount, plural, =1 {変換} other {変換}}の削除に失敗しました", "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "{totalCount, plural, =1 {変換} other {変換}}の開始に失敗しました", @@ -43470,7 +43440,6 @@ "unifiedDocViewer.sourceViewer.errorMessageTitle": "エラーが発生しました", "unifiedDocViewer.sourceViewer.refresh": "更新", "utils.filename.pathWarning": "パスの形式が正しくない可能性があります。値を検証してください", - "utils.filename.wildcardWarning": "ファイルパスでワイルドカードを使用すると、エンドポイントのパフォーマンスに影響する可能性があります", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.description": "Visualizeでゲージグラフのレガシーグラフライブラリを有効にします。", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.name": "ゲージグラフのレガシーグラフライブラリ", "visTypeGauge.controls.gaugeOptions.alignmentLabel": "アラインメント", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index ca068f37c938..193f14b2df05 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5322,7 +5322,6 @@ "savedSearch.kibana_context.savedSearchId.help": "指定要用于查询和筛选的已保存搜索 ID", "savedSearch.kibana_context.timeRange.help": "指定 Kibana 时间范围筛选", "searchApiPanels.welcomeBanner.header.greeting.customTitle": "{name}您好!", - "searchApiPanels.welcomeBanner.ingestData.clientDocLink": "{languageName} API 参考", "searchApiPanels.welcomeBanner.installClient.clientDocLink": "{languageName} 客户端文档", "searchApiPanels.welcomeBanner.selectClient.description": "Elastic 以几种流行语言构建和维护客户端,我们的社区也做出了许多贡献。选择您常用的语言客户端或深入分析 {console} 以开始使用。", "searchApiPanels.welcomeBanner.codeBox.copyButtonLabel": "复制", @@ -5330,22 +5329,7 @@ "searchApiPanels.welcomeBanner.header.description": "设置您的编程语言客户端,采集一些数据,如此即可在数分钟内开始搜索。", "searchApiPanels.welcomeBanner.header.greeting.defaultTitle": "您好!", "searchApiPanels.welcomeBanner.header.title": "Elasticsearch 入门", - "searchApiPanels.welcomeBanner.ingestData.beatsDescription": "用于 Elasticsearch 的轻量级、单一用途数据采集器。使用 Beats 从您的服务器发送运营数据。", - "searchApiPanels.welcomeBanner.ingestData.beatsLink": "Beats", - "searchApiPanels.welcomeBanner.ingestData.beatsTitle": "Beats", - "searchApiPanels.welcomeBanner.ingestData.connectorsDescription": "用于将数据从第三方源同步到 Elasticsearch 的专用集成。使用 Elastic 连接器同步来自一系列数据库和对象存储的内容。", - "searchApiPanels.welcomeBanner.ingestData.connectorsPythonLink": "connectors-python", - "searchApiPanels.welcomeBanner.ingestData.connectorsTitle": "连接器客户端", "searchApiPanels.welcomeBanner.ingestData.description": "将数据添加到数据流或索引,使其可进行搜索。选择适合您的应用程序和工作流的集成方法。", - "searchApiPanels.welcomeBanner.ingestData.ingestApiDescription": "最灵活的数据索引方法,允许您全面控制定制和优化选项。", - "searchApiPanels.welcomeBanner.ingestData.ingestApiLabel": "通过 API 采集", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationDescription": "针对转换数据并将其传输到 Elasticsearch 而优化的专用采集工具。", - "searchApiPanels.welcomeBanner.ingestData.ingestIntegrationLabel": "通过集成采集", - "searchApiPanels.welcomeBanner.ingestData.ingestLegendLabel": "选择采集方法", - "searchApiPanels.welcomeBanner.ingestData.integrationsLink": "关于集成", - "searchApiPanels.welcomeBanner.ingestData.logstashDescription": "将数据添加到数据流或索引,使其可进行搜索。选择适合您的应用程序和工作流的集成方法。", - "searchApiPanels.welcomeBanner.ingestData.logstashLink": "Logstash", - "searchApiPanels.welcomeBanner.ingestData.logstashTitle": "Logstash", "searchApiPanels.welcomeBanner.ingestData.title": "采集数据", "searchApiPanels.welcomeBanner.installClient.description": "Elastic 以几种流行语言构建和维护客户端,我们的社区也做出了许多贡献。安装您常用的语言客户端以开始使用。", "searchApiPanels.welcomeBanner.installClient.title": "安装客户端", @@ -14460,18 +14444,18 @@ "xpack.enterpriseSearch.content.index.pipelines.settings.reduceWhitespaceLabel": "减少空白", "xpack.enterpriseSearch.content.index.pipelines.settings.runMlInferenceDescrition": "使用兼容的已训练 ML 模型增强您的数据", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployedBody": "您可以在单线程配置中启动模型以用于测试,或调整性能以用于生产环境。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployedTitle": "您的 ELSER v2 模型已部署,但尚未启动。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployedTitle": "您的 ELSER 模型已部署,但尚未启动。", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployingBody": "同时,您可以继续使用其他上传的模型来创建管道。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployingTitle": "您的 ELSER v2 模型正在部署。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.deployingTitle": "您的 ELSER 模型正在部署。", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.dismissButton": "关闭 ELSER 对外调用", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.learnMoreLink": "了解详情", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedBody": "在您的定制推理管道中体验 ELSER v2 的强大功能。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedBody": "在您的定制推理管道中体验 ELSER 的强大功能。", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedBody": "此单线程配置非常适合测试您的定制推理管道,但应微调性能以用于生产。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitle": "您的 ELSER v2 模型已通过单线程方式启动。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitleCompact": "您的 ELSER v2 模型正通过单线程方式运行。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitle": "您的 ELSER v2 模型已启动。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitleCompact": "您的 ELSER v2 模型正在运行。", - "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.title": "通过 ELSER v2 改进您的结果", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitle": "您的 ELSER 模型已通过单线程方式启动。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedSingleThreadedTitleCompact": "您的 ELSER 模型正通过单线程方式运行。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitle": "您的 ELSER 模型已启动。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.startedTitleCompact": "您的 ELSER 模型正在运行。", + "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.title": "通过 ELSER 改进您的结果", "xpack.enterpriseSearch.content.index.pipelines.textExpansionCallOut.titleBadge": "新建", "xpack.enterpriseSearch.content.index.searchApplication.createSearchApplication": "创建搜索应用程序", "xpack.enterpriseSearch.content.index.searchEngines.createEngineDisabledTooltip": "无法从隐藏索引创建搜索应用程序。", @@ -14741,9 +14725,9 @@ "xpack.enterpriseSearch.content.indices.pipelines.textExpansionCallOut.startModelButton.label": "以单线程方式启动", "xpack.enterpriseSearch.content.indices.pipelines.textExpansionCallOut.viewModelsButton": "查看详情", "xpack.enterpriseSearch.content.indices.pipelines.textExpansionCreateError.mlNotificationsLink": "Machine Learning 通知", - "xpack.enterpriseSearch.content.indices.pipelines.textExpansionCreateError.title": "ELSER v2 部署出错", - "xpack.enterpriseSearch.content.indices.pipelines.textExpansionFetchError.title": "提取 ELSER v2 模型时出错", - "xpack.enterpriseSearch.content.indices.pipelines.textExpansionStartError.title": "启动 ELSER v2 部署时出错", + "xpack.enterpriseSearch.content.indices.pipelines.textExpansionCreateError.title": "ELSER 部署出错", + "xpack.enterpriseSearch.content.indices.pipelines.textExpansionFetchError.title": "提取 ELSER 模型时出错", + "xpack.enterpriseSearch.content.indices.pipelines.textExpansionStartError.title": "启动 ELSER 部署时出错", "xpack.enterpriseSearch.content.indices.searchIndex.convertConnector.buttonLabel": "转换连接器", "xpack.enterpriseSearch.content.indices.selectConnector.allConnectorsLabel": "所有连接器", "xpack.enterpriseSearch.content.indices.selectConnector.callout.description.connectorsClient": "连接器客户端", @@ -18649,9 +18633,7 @@ "xpack.grokDebugger.unknownErrorTitle": "出问题了", "xpack.idxMgmt.badgeAriaLabel": "{label}。选择以基于其进行筛选。", "xpack.idxMgmt.clearCacheIndicesAction.indexCacheClearedMessage": "已清除索引 {indexNames} 的缓存。", - "xpack.idxMgmt.clearCacheIndicesAction.successMessage": "已成功清除缓存:[{indexNames}]", "xpack.idxMgmt.closeIndicesAction.indexClosedMessage": "索引 {indexNames} 已关闭。", - "xpack.idxMgmt.closeIndicesAction.successfullyClosedIndicesMessage": "已成功关闭:[{indexNames}]", "xpack.idxMgmt.componentTemplateDetails.summaryTab.notInUseDescription": "{createLink}索引模板或{editLink}现有索引模板。", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaDescription": "有关模板的任意信息,以集群状态存储。{learnMoreLink}", "xpack.idxMgmt.componentTemplateForm.stepLogistics.metaHelpText": "使用 JSON 格式:{code}", @@ -18670,7 +18652,6 @@ "xpack.idxMgmt.deleteDataStreamsConfirmationModal.multipleErrorsNotificationMessageText": "删除 {count} 个数据流时出错", "xpack.idxMgmt.deleteDataStreamsConfirmationModal.successDeleteMultipleNotificationMessageText": "已删除 {numSuccesses, plural, other {# 个数据流}}", "xpack.idxMgmt.deleteIndicesAction.indexDeletedMessage": "索引 {indexNames} 已删除。", - "xpack.idxMgmt.deleteIndicesAction.successfullyDeletedIndicesMessage": "已成功删除:[{indexNames}]", "xpack.idxMgmt.deleteTemplatesModal.confirmButtonLabel": "删除 {numTemplatesToDelete, plural, other {模板}}", "xpack.idxMgmt.deleteTemplatesModal.deleteDescription": "您即将删除{numTemplatesToDelete, plural, other {以下模板}}:", "xpack.idxMgmt.deleteTemplatesModal.modalTitleText": "删除 {numTemplatesToDelete, plural, other {# 个模板}}", @@ -18688,9 +18669,7 @@ "xpack.idxMgmt.enrichPolicyCreate.configurationStep.queryHelpText": "默认为:{code} 查询。", "xpack.idxMgmt.enrichPolicyCreate.configurationStep.rangeTypePopOver": "{type} 匹配一个数字、日期或 IP 地址范围。", "xpack.idxMgmt.flushIndicesAction.indexFlushedMessage": "索引 {indexNames} 已清空。", - "xpack.idxMgmt.flushIndicesAction.successfullyFlushedIndicesMessage": "已成功清空:[{indexNames}]", "xpack.idxMgmt.forceMergeIndicesAction.indexForcemergedMessage": "已强制合并索引 {indexNames}。", - "xpack.idxMgmt.forceMergeIndicesAction.successfullyForceMergedIndicesMessage": "已成功强制合并:[{indexNames}]", "xpack.idxMgmt.formWizard.stepAliases.aliasesEditorHelpText": "使用 JSON 格式:{code}", "xpack.idxMgmt.formWizard.stepSettings.settingsEditorHelpText": "使用 JSON 格式:{code}", "xpack.idxMgmt.goToDiscover.showIndexToolTip": "在 Discover 中显示 {indexName}", @@ -18787,9 +18766,7 @@ "xpack.idxMgmt.mappingsEditor.sourceFieldDescription": "_source 字段包含在索引时提供的原始 JSON 文档正文。单个字段可通过定义哪些字段可以在 _source 字段中包括或排除来进行修剪。{docsLink}", "xpack.idxMgmt.mappingsEditor.typeField.documentationLinkLabel": "{typeName} 文档", "xpack.idxMgmt.openIndicesAction.indexOpenedMessage": "索引 {indexNames} 已打开。", - "xpack.idxMgmt.openIndicesAction.successfullyOpenedIndicesMessage": "已成功打开:[{indexNames}]", "xpack.idxMgmt.refreshIndicesAction.indexRefreshedMessage": "索引 {indexNames} 已刷新。", - "xpack.idxMgmt.refreshIndicesAction.successfullyRefreshedIndicesMessage": "已成功刷新:[{indexNames}]", "xpack.idxMgmt.templateDetails.summaryTab.indexPatternsDescriptionListTitle": "索引{numIndexPatterns, plural, other {模式}}", "xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription": "该模板创建数据流,而非索引。{docsLink}", "xpack.idxMgmt.templateForm.stepLogistics.fieldIndexPatternsHelpText": "不允许使用空格和字符 {invalidCharactersList}。", @@ -22362,7 +22339,6 @@ "xpack.lens.config.configFlyoutCallout": "ES|QL 当前提供的配置选项数量有限", "xpack.lens.config.editLabel": "编辑配置", "xpack.lens.config.editLinkLabel": "在 Lens 中编辑", - "xpack.lens.config.editVisualizationLabel": "编辑可视化", "xpack.lens.config.experimentalLabel": "技术预览", "xpack.lens.configPanel.addLayerButton": "添加图层", "xpack.lens.configPanel.experimentalLabel": "技术预览", @@ -25343,7 +25319,7 @@ "xpack.ml.dataFrame.analytics.create.searchSelection.CcsErrorCallOutTitle": "不支持使用跨集群搜索的数据视图。", "xpack.ml.dataFrame.analytics.create.searchSelection.errorGettingDataViewTitle": "加载已保存搜索所使用的数据视图时出错", "xpack.ml.dataFrame.analytics.create.searchSelection.notFoundLabel": "未找到匹配的索引或已保存搜索。", - "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.indexPattern": "数据视图", + "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.dataView": "数据视图", "xpack.ml.dataFrame.analytics.create.searchSelection.savedObjectType.search": "已保存搜索", "xpack.ml.dataframe.analytics.create.shouldCreateDataViewMessage": "如果没有为目标索引创建数据视图,则可能无法查看作业结果。", "xpack.ml.dataframe.analytics.create.softTreeDepthLimitInputAriaLabel": "超过此深度的决策树将在损失计算中被罚分。", @@ -29231,7 +29207,6 @@ "xpack.observability.customThreshold.rule.alertFlyout.customEquationTooltip": "这支持基本数学 (A + B / C) 和布尔逻辑 (A < B ?A :B)。", "xpack.observability.customThreshold.rule.alertFlyout.dataViewError.noTimestamp": "选定数据视图没有时间戳字段,请选择其他数据视图。", "xpack.observability.customThreshold.rule.alertFlyout.defineTextQueryPrompt": "定义查询筛选(可选)", - "xpack.observability.customThreshold.rule.alertFlyout.error.aggregationRequired": "“聚合”必填。", "xpack.observability.customThreshold.rule.alertFlyout.error.equation.invalidCharacters": "方程字段仅支持以下字符:A-Z、+、-、/、*、(、)、?、!、&、:、|、>、<、=", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidFilterQuery": "筛选查询无效。", "xpack.observability.customThreshold.rule.alertFlyout.error.invalidSearchConfiguration": "需要数据视图。", @@ -32352,12 +32327,7 @@ "xpack.securitySolution.responseActionsList.list.recordRange": "正在显示第 {range} 个(共 {total} 个){recordsLabel}", "xpack.securitySolution.responseActionsList.list.recordRangeLabel": "{records, plural, other {响应操作}}", "xpack.securitySolution.riskInformation.howCalculatedText": "实体风险引擎每小时运行一次,以聚合过去 30 天出现的“未结”和“已确认”告警,并为主机或用户分配风险分数。然后,它会聚合各个风险分数并使用 {riemannZetaLink} 将其标准化为 0-100 范围。", - "xpack.securitySolution.riskInformation.learnMore": "详细了解 {riskEntity} 风险", "xpack.securitySolution.riskInformation.riskHeader": "{riskEntity} 风险分数范围", - "xpack.securitySolution.riskInformation.riskScoreFieldLabel": "{riskEntity} 风险分数", - "xpack.securitySolution.riskInformation.riskScoreFieldText": "{riskScoreField} 字段以单个数字值表示 {riskEntity} 的标准化风险。您可以在分类和响应 playbook 中将此值用作相对风险指标。", - "xpack.securitySolution.riskInformation.riskScoreLevelLabel": "{riskEntity} 风险级别", - "xpack.securitySolution.riskInformation.riskScoreLevelText": "{riskLevelField} 字段根据预定义的风险指标表示 {riskEntity} 的六个风险级别之一。", "xpack.securitySolution.riskScore.api.ingestPipeline.delete.errorMessageTitle": "无法删除采集{totalCount, plural, =1 {管道} other {管道}}", "xpack.securitySolution.riskScore.api.transforms.delete.errorMessageTitle": "无法删除{totalCount, plural, =1 {转换} other {转换}}", "xpack.securitySolution.riskScore.api.transforms.start.errorMessageTitle": "无法启动{totalCount, plural, =1 {转换} other {转换}}", @@ -43464,7 +43434,6 @@ "unifiedDocViewer.sourceViewer.errorMessageTitle": "发生错误", "unifiedDocViewer.sourceViewer.refresh": "刷新", "utils.filename.pathWarning": "路径的格式可能不正确;请验证值", - "utils.filename.wildcardWarning": "在文件路径中使用通配符可能会影响终端性能", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.description": "在 Visualize 中启用仪表盘图表的旧版图表库。", "visTypeGauge.advancedSettings.visualization.legacyGaugeChartsLibrary.name": "仪表盘旧版图表库", "visTypeGauge.controls.gaugeOptions.alignmentLabel": "对齐方式", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.ts deleted file mode 100644 index ef1bdee1d549..000000000000 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.ts +++ /dev/null @@ -1,111 +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 { AlertConsumers } from '@kbn/rule-data-utils'; -import { createStartServicesMock } from '../../common/lib/kibana/kibana_react.mock'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; -import { act, renderHook } from '@testing-library/react-hooks'; -import { useAlertDataView, UserAlertDataView } from './use_alert_data_view'; - -const mockUseKibanaReturnValue = createStartServicesMock(); - -jest.mock('@kbn/kibana-react-plugin/public', () => ({ - __esModule: true, - useKibana: jest.fn(() => ({ - services: mockUseKibanaReturnValue, - })), -})); - -describe('useAlertDataView', () => { - const observabilityAlertFeatureIds: ValidFeatureId[] = [ - AlertConsumers.APM, - AlertConsumers.INFRASTRUCTURE, - AlertConsumers.LOGS, - AlertConsumers.UPTIME, - ]; - - beforeEach(() => { - mockUseKibanaReturnValue.http.get = jest.fn().mockReturnValue({ - index_name: [ - '.alerts-observability.uptime.alerts-*', - '.alerts-observability.metrics.alerts-*', - '.alerts-observability.logs.alerts-*', - '.alerts-observability.apm.alerts-*', - ], - }); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - it('initially is loading and does not have data', async () => { - await act(async () => { - const mockedAsyncDataView = { - loading: true, - error: undefined, - }; - - const { result, waitForNextUpdate } = renderHook(() => - useAlertDataView(observabilityAlertFeatureIds) - ); - - await waitForNextUpdate(); - - expect(result.current).toEqual(mockedAsyncDataView); - }); - }); - - it('returns dataView for the provided featureIds', async () => { - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => - useAlertDataView(observabilityAlertFeatureIds) - ); - - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toMatchInlineSnapshot(` - Object { - "error": undefined, - "loading": false, - "value": Array [ - Object { - "fieldFormatMap": Object {}, - "fields": Array [], - "title": ".alerts-observability.uptime.alerts-*,.alerts-observability.metrics.alerts-*,.alerts-observability.logs.alerts-*,.alerts-observability.apm.alerts-*", - }, - ], - } - `); - }); - }); - - it('returns error with no data when error happens', async () => { - const error = new Error('http error'); - mockUseKibanaReturnValue.http.get = jest.fn().mockImplementation(async () => { - throw error; - }); - - await act(async () => { - const { result, waitForNextUpdate } = renderHook(() => - useAlertDataView(observabilityAlertFeatureIds) - ); - - await waitForNextUpdate(); - await waitForNextUpdate(); - - expect(result.current).toMatchInlineSnapshot(` - Object { - "error": [Error: http error], - "loading": false, - "value": undefined, - } - `); - }); - }); -}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.tsx new file mode 100644 index 000000000000..e37808a05d9b --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.test.tsx @@ -0,0 +1,162 @@ +/* + * 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 { AlertConsumers } from '@kbn/rule-data-utils'; +import { createStartServicesMock } from '../../common/lib/kibana/kibana_react.mock'; +import type { ValidFeatureId } from '@kbn/rule-data-utils'; +import { act, renderHook } from '@testing-library/react-hooks'; +import { useAlertDataView } from './use_alert_data_view'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import React from 'react'; + +const mockUseKibanaReturnValue = createStartServicesMock(); + +jest.mock('@kbn/kibana-react-plugin/public', () => ({ + __esModule: true, + useKibana: jest.fn(() => ({ + services: mockUseKibanaReturnValue, + })), +})); + +jest.mock('../lib/rule_api/alert_index', () => ({ + fetchAlertIndexNames: jest.fn(), +})); + +const { fetchAlertIndexNames } = jest.requireMock('../lib/rule_api/alert_index'); + +jest.mock('../lib/rule_api/alert_fields', () => ({ + fetchAlertFields: jest.fn(), +})); +const { fetchAlertFields } = jest.requireMock('../lib/rule_api/alert_fields'); + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + cacheTime: 0, + }, + }, +}); +const wrapper = ({ children }: { children: Node }) => ( + {children} +); + +describe('useAlertDataView', () => { + const observabilityAlertFeatureIds: ValidFeatureId[] = [ + AlertConsumers.APM, + AlertConsumers.INFRASTRUCTURE, + AlertConsumers.LOGS, + AlertConsumers.UPTIME, + ]; + + beforeEach(() => { + fetchAlertIndexNames.mockResolvedValue([ + '.alerts-observability.uptime.alerts-*', + '.alerts-observability.metrics.alerts-*', + '.alerts-observability.logs.alerts-*', + '.alerts-observability.apm.alerts-*', + ]); + fetchAlertFields.mockResolvedValue([{ data: ' fields' }]); + }); + + afterEach(() => { + queryClient.clear(); + jest.clearAllMocks(); + }); + + it('initially is loading and does not have data', async () => { + await act(async () => { + const mockedAsyncDataView = { + loading: true, + dataview: undefined, + }; + + const { result, waitForNextUpdate } = renderHook( + () => useAlertDataView(observabilityAlertFeatureIds), + { + wrapper, + } + ); + + await waitForNextUpdate(); + + expect(result.current).toEqual(mockedAsyncDataView); + }); + }); + + it('fetch index names + fields for the provided o11y featureIds', async () => { + await act(async () => { + const { waitForNextUpdate } = renderHook( + () => useAlertDataView(observabilityAlertFeatureIds), + { + wrapper, + } + ); + + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(fetchAlertIndexNames).toHaveBeenCalledTimes(1); + expect(fetchAlertFields).toHaveBeenCalledTimes(1); + }); + }); + + it('only fetch index names for security featureId', async () => { + await act(async () => { + const { waitForNextUpdate } = renderHook(() => useAlertDataView([AlertConsumers.SIEM]), { + wrapper, + }); + + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(fetchAlertIndexNames).toHaveBeenCalledTimes(1); + expect(fetchAlertFields).toHaveBeenCalledTimes(0); + }); + }); + + it('Do not fetch anything if security and o11y featureIds are mix together', async () => { + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => useAlertDataView([AlertConsumers.SIEM, AlertConsumers.LOGS]), + { + wrapper, + } + ); + + await waitForNextUpdate(); + + expect(fetchAlertIndexNames).toHaveBeenCalledTimes(0); + expect(fetchAlertFields).toHaveBeenCalledTimes(0); + expect(result.current).toEqual({ + loading: false, + dataview: undefined, + }); + }); + }); + + it('if fetch throw error return no data', async () => { + fetchAlertIndexNames.mockRejectedValue('error'); + + await act(async () => { + const { result, waitForNextUpdate } = renderHook( + () => useAlertDataView(observabilityAlertFeatureIds), + { + wrapper, + } + ); + + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(result.current).toEqual({ + loading: false, + dataview: undefined, + }); + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.ts index 15608192e7dd..7b72e5898d56 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_alert_data_view.ts @@ -5,72 +5,158 @@ * 2.0. */ -import { DataView, FieldSpec } from '@kbn/data-views-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { DataView } from '@kbn/data-views-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; -import type { ValidFeatureId } from '@kbn/rule-data-utils'; -import useAsync from 'react-use/lib/useAsync'; -import { useMemo } from 'react'; +import { AlertConsumers, ValidFeatureId } from '@kbn/rule-data-utils'; +import { useEffect, useMemo, useState } from 'react'; +import { useQuery } from '@tanstack/react-query'; import { TriggersAndActionsUiServices } from '../..'; +import { fetchAlertIndexNames } from '../lib/rule_api/alert_index'; +import { fetchAlertFields } from '../lib/rule_api/alert_fields'; export interface UserAlertDataView { - value?: DataView[]; + dataviews?: DataView[]; loading: boolean; - error?: Error; } export function useAlertDataView(featureIds: ValidFeatureId[]): UserAlertDataView { - const { http } = useKibana().services; + const { + http, + data: dataService, + notifications: { toasts }, + } = useKibana().services; + const [dataviews, setDataviews] = useState(undefined); const features = featureIds.sort().join(','); + const isOnlySecurity = featureIds.length === 1 && featureIds.includes(AlertConsumers.SIEM); - const indexNames = useAsync(async () => { - const { index_name: indexNamesStr } = await http.get<{ index_name: string[] }>( - `${BASE_RAC_ALERTS_API_PATH}/index`, - { - query: { features }, - } - ); + const hasSecurityAndO11yFeatureIds = + featureIds.length > 1 && featureIds.includes(AlertConsumers.SIEM); - return indexNamesStr; - }, [features]); + const hasNoSecuritySolution = + featureIds.length > 0 && !isOnlySecurity && !hasSecurityAndO11yFeatureIds; - const fields = useAsync(async () => { - const { fields: alertFields } = await http.get<{ fields: FieldSpec[] }>( - `${BASE_RAC_ALERTS_API_PATH}/browser_fields`, - { - query: { featureIds }, - } - ); - return alertFields; - }, [features]); + const queryIndexNameFn = () => { + return fetchAlertIndexNames({ http, features }); + }; - const dataview = useMemo( - () => - !fields.loading && - !indexNames.loading && - fields.error === undefined && - indexNames.error === undefined - ? ([ - { - title: (indexNames.value ?? []).join(','), - fieldFormatMap: {}, - fields: (fields.value ?? [])?.map((field) => { - return { - ...field, - ...(field.esTypes && field.esTypes.includes('flattened') - ? { type: 'string' } - : {}), - }; - }), - }, - ] as unknown as DataView[]) - : undefined, - [fields, indexNames] - ); + const queryAlertFieldsFn = () => { + return fetchAlertFields({ http, featureIds }); + }; - return { - value: dataview, - loading: fields.loading || indexNames.loading, - error: fields.error ? fields.error : indexNames.error, + const onErrorFn = () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.useAlertDataView.useAlertDataMessage', { + defaultMessage: 'Unable to load alert data view', + }) + ); }; + + const { + data: indexNames, + isSuccess: isIndexNameSuccess, + isInitialLoading: isIndexNameInitialLoading, + isLoading: isIndexNameLoading, + } = useQuery({ + queryKey: ['loadAlertIndexNames', features], + queryFn: queryIndexNameFn, + onError: onErrorFn, + refetchOnWindowFocus: false, + enabled: featureIds.length > 0 && !hasSecurityAndO11yFeatureIds, + }); + + const { + data: alertFields, + isSuccess: isAlertFieldsSuccess, + isInitialLoading: isAlertFieldsInitialLoading, + isLoading: isAlertFieldsLoading, + } = useQuery({ + queryKey: ['loadAlertFields', features], + queryFn: queryAlertFieldsFn, + onError: onErrorFn, + refetchOnWindowFocus: false, + enabled: hasNoSecuritySolution, + }); + + useEffect(() => { + return () => { + dataviews?.map((dv) => { + dataService.dataViews.clearInstanceCache(dv.id); + }); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [dataviews]); + + // FUTURE ENGINEER this useEffect is for security solution user since + // we are using the user privilege to access the security alert index + useEffect(() => { + async function createDataView() { + const localDataview = await dataService.dataViews.create({ + title: (indexNames ?? []).join(','), + allowNoIndex: true, + }); + setDataviews([localDataview]); + } + + if (isOnlySecurity && isIndexNameSuccess) { + createDataView(); + } + }, [dataService.dataViews, indexNames, isIndexNameSuccess, isOnlySecurity]); + + // FUTURE ENGINEER this useEffect is for o11y and stack solution user since + // we are using the kibana user privilege to access the alert index + useEffect(() => { + if ( + indexNames && + alertFields && + !isOnlySecurity && + isAlertFieldsSuccess && + isIndexNameSuccess + ) { + setDataviews([ + { + title: (indexNames ?? []).join(','), + fieldFormatMap: {}, + fields: (alertFields ?? [])?.map((field) => { + return { + ...field, + ...(field.esTypes && field.esTypes.includes('flattened') ? { type: 'string' } : {}), + }; + }), + }, + ] as unknown as DataView[]); + } + }, [ + alertFields, + dataService.dataViews, + indexNames, + isIndexNameSuccess, + isOnlySecurity, + isAlertFieldsSuccess, + ]); + + return useMemo( + () => ({ + dataviews, + loading: + featureIds.length === 0 || hasSecurityAndO11yFeatureIds + ? false + : isOnlySecurity + ? isIndexNameInitialLoading || isIndexNameLoading + : isIndexNameInitialLoading || + isIndexNameLoading || + isAlertFieldsInitialLoading || + isAlertFieldsLoading, + }), + [ + dataviews, + featureIds.length, + hasSecurityAndO11yFeatureIds, + isOnlySecurity, + isIndexNameInitialLoading, + isIndexNameLoading, + isAlertFieldsInitialLoading, + isAlertFieldsLoading, + ] + ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_types_query.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_types_query.ts index 4892341e5738..ab11bb4f1845 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_types_query.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_load_rule_types_query.ts @@ -13,6 +13,7 @@ import { RuleType, RuleTypeIndex } from '../../types'; interface UseLoadRuleTypesQueryProps { filteredRuleTypes: string[]; + enabled?: boolean; } const getFilteredIndex = (data: Array>, filteredRuleTypes: string[]) => { @@ -32,7 +33,7 @@ const getFilteredIndex = (data: Array>, filteredRuleTyp }; export const useLoadRuleTypesQuery = (props: UseLoadRuleTypesQueryProps) => { - const { filteredRuleTypes } = props; + const { filteredRuleTypes, enabled = true } = props; const { http, notifications: { toasts }, @@ -55,6 +56,7 @@ export const useLoadRuleTypesQuery = (props: UseLoadRuleTypesQueryProps) => { queryFn, onError: onErrorFn, refetchOnWindowFocus: false, + enabled, }); const filteredIndex = data ? getFilteredIndex(data, filteredRuleTypes) : new Map(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts index 7fa2e3f0dfd0..1ad710691011 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts @@ -8,21 +8,67 @@ import { DataViewField } from '@kbn/data-views-plugin/common'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; -import useAsync from 'react-use/lib/useAsync'; -import type { AsyncState } from 'react-use/lib/useAsync'; +import { HttpSetup } from '@kbn/core/public'; +import { useQuery } from '@tanstack/react-query'; +import { i18n } from '@kbn/i18n'; +import { useMemo } from 'react'; import { TriggersAndActionsUiServices } from '../..'; -export function useRuleAADFields(ruleTypeId?: string): AsyncState { - const { http } = useKibana().services; +const EMPTY_AAD_FIELDS: DataViewField[] = []; - const aadFields = useAsync(async () => { - if (!ruleTypeId) return []; - const fields = await http.get(`${BASE_RAC_ALERTS_API_PATH}/aad_fields`, { - query: { ruleTypeId }, - }); +async function fetchAadFields({ + http, + ruleTypeId, +}: { + http: HttpSetup; + ruleTypeId?: string; +}): Promise { + if (!ruleTypeId) return EMPTY_AAD_FIELDS; + const fields = await http.get(`${BASE_RAC_ALERTS_API_PATH}/aad_fields`, { + query: { ruleTypeId }, + }); + + return fields; +} + +export function useRuleAADFields(ruleTypeId?: string): { + aadFields: DataViewField[]; + loading: boolean; +} { + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const queryAadFieldsFn = () => { + return fetchAadFields({ http, ruleTypeId }); + }; + + const onErrorFn = () => { + toasts.addDanger( + i18n.translate('xpack.triggersActionsUI.useRuleAADFields.errorMessage', { + defaultMessage: 'Unable to load alert fields per rule type', + }) + ); + }; - return fields; + const { + data: aadFields = EMPTY_AAD_FIELDS, + isInitialLoading, + isLoading, + } = useQuery({ + queryKey: ['loadAlertAadFieldsPerRuleType', ruleTypeId], + queryFn: queryAadFieldsFn, + onError: onErrorFn, + refetchOnWindowFocus: false, + enabled: ruleTypeId !== undefined, }); - return aadFields; + return useMemo( + () => ({ + aadFields, + loading: ruleTypeId === undefined ? false : isInitialLoading || isLoading, + }), + [aadFields, isInitialLoading, isLoading, ruleTypeId] + ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_fields.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_fields.ts new file mode 100644 index 000000000000..7be5b3eec0e6 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_fields.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ValidFeatureId } from '@kbn/rule-data-utils'; +import { HttpSetup } from '@kbn/core/public'; +import { FieldSpec } from '@kbn/data-views-plugin/common'; +import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; + +export async function fetchAlertFields({ + http, + featureIds, +}: { + http: HttpSetup; + featureIds: ValidFeatureId[]; +}): Promise { + const { fields: alertFields = [] } = await http.get<{ fields: FieldSpec[] }>( + `${BASE_RAC_ALERTS_API_PATH}/browser_fields`, + { + query: { featureIds }, + } + ); + return alertFields; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_index.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_index.ts new file mode 100644 index 000000000000..8ac678664168 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/alert_index.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 { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common'; +import { HttpSetup } from '@kbn/core/public'; + +export async function fetchAlertIndexNames({ + http, + features, +}: { + http: HttpSetup; + features: string; +}): Promise { + const { index_name: indexNamesStr = [] } = await http.get<{ index_name: string[] }>( + `${BASE_RAC_ALERTS_API_PATH}/index`, + { + query: { features }, + } + ); + return indexNamesStr; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index 83ad089c8e69..a9f49f609e13 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -8,7 +8,7 @@ import React, { Suspense, useEffect, useState, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ValidFeatureId, AlertConsumers } from '@kbn/rule-data-utils'; +import { ValidFeatureId } from '@kbn/rule-data-utils'; import { EuiFlexGroup, EuiFlexItem, @@ -428,8 +428,7 @@ export const ActionTypeForm = ({ setActionGroupIdByIndex && !actionItem.frequency?.summary; - const showActionAlertsFilter = - hasFieldsForAAD || producerId === AlertConsumers.SIEM || hasAlertsMappings; + const showActionAlertsFilter = hasFieldsForAAD; const accordionContent = checkEnabledResult.isEnabled ? ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx index 077be38b5616..10e2a8493d71 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_search_bar/alerts_search_bar.tsx @@ -9,12 +9,14 @@ import React, { useCallback, useState } from 'react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; import { Query, TimeRange } from '@kbn/es-query'; import { SuggestionsAbstraction } from '@kbn/unified-search-plugin/public/typeahead/suggestions_component'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { NO_INDEX_PATTERNS } from './constants'; import { SEARCH_BAR_PLACEHOLDER } from './translations'; import { AlertsSearchBarProps, QueryLanguageType } from './types'; import { useAlertDataView } from '../../hooks/use_alert_data_view'; import { TriggersAndActionsUiServices } from '../../..'; import { useRuleAADFields } from '../../hooks/use_rule_aad_fields'; +import { useLoadRuleTypesQuery } from '../../hooks/use_load_rule_types_query'; const SA_ALERTS = { type: 'alerts', fields: {} } as SuggestionsAbstraction; @@ -44,15 +46,22 @@ export function AlertsSearchBar({ } = useKibana().services; const [queryLanguage, setQueryLanguage] = useState('kuery'); - const { value: dataView, loading, error } = useAlertDataView(featureIds); - const { - value: aadFields, - loading: fieldsLoading, - error: fieldsError, - } = useRuleAADFields(ruleTypeId); + const { dataviews, loading } = useAlertDataView(featureIds ?? []); + const { aadFields, loading: fieldsLoading } = useRuleAADFields(ruleTypeId); const indexPatterns = - ruleTypeId && aadFields?.length ? [{ title: ruleTypeId, fields: aadFields }] : dataView; + ruleTypeId && aadFields?.length ? [{ title: ruleTypeId, fields: aadFields }] : dataviews; + + const ruleType = useLoadRuleTypesQuery({ + filteredRuleTypes: ruleTypeId !== undefined ? [ruleTypeId] : [], + enabled: ruleTypeId !== undefined, + }); + + const isSecurity = + (featureIds && featureIds.length === 1 && featureIds.includes(AlertConsumers.SIEM)) || + (ruleType && + ruleTypeId && + ruleType.ruleTypesState.data.get(ruleTypeId)?.producer === AlertConsumers.SIEM); const onSearchQuerySubmit = useCallback( ({ dateRange, query: nextQuery }: { dateRange: TimeRange; query?: Query }) => { @@ -86,9 +95,7 @@ export function AlertsSearchBar({ appName={appName} disableQueryLanguageSwitcher={disableQueryLanguageSwitcher} // @ts-expect-error - DataView fields prop and SearchBar indexPatterns props are overly broad - indexPatterns={ - loading || error || fieldsLoading || fieldsError ? NO_INDEX_PATTERNS : indexPatterns - } + indexPatterns={loading || fieldsLoading ? NO_INDEX_PATTERNS : indexPatterns} placeholder={placeholder} query={{ query: query ?? '', language: queryLanguage }} filters={filters} @@ -105,7 +112,7 @@ export function AlertsSearchBar({ showSubmitButton={showSubmitButton} submitOnBlur={submitOnBlur} onQueryChange={onSearchQueryChange} - suggestionsAbstraction={SA_ALERTS} + suggestionsAbstraction={isSecurity ? undefined : SA_ALERTS} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx index de2eb91b74c8..aab0b5891fc7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx @@ -305,6 +305,7 @@ const RuleAdd = ({ hideGrouping={hideGrouping} hideInterval={hideInterval} onChangeMetaData={onChangeMetaData} + selectedConsumer={selectedConsumer} setConsumer={setSelectedConsumer} useRuleProducer={useRuleProducer} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx index 59d3c4f1f8c3..f528ce4b45aa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx @@ -262,6 +262,7 @@ describe('rule_form', () => { ruleTypesOverwrite?: RuleType[]; ruleTypeModelOverwrite?: RuleTypeModel; useRuleProducer?: boolean; + selectedConsumer?: RuleCreationValidConsumer | null; }) { const { showRulesList = false, @@ -273,6 +274,7 @@ describe('rule_form', () => { ruleTypesOverwrite, ruleTypeModelOverwrite, useRuleProducer = false, + selectedConsumer, } = options || {}; const mocks = coreMock.createSetup(); @@ -325,7 +327,11 @@ describe('rule_form', () => { enabledInLicense: false, }, ]; - useLoadRuleTypes.mockReturnValue({ ruleTypes }); + const ruleTypeIndex = ruleTypes.reduce((acc, item) => { + acc.set(item.id, item); + return acc; + }, new Map()); + useLoadRuleTypes.mockReturnValue({ ruleTypes, ruleTypeIndex }); const [ { application: { capabilities }, @@ -377,7 +383,7 @@ describe('rule_form', () => { minimumScheduleInterval: { value: '1m', enforce: enforceMinimum }, }} dispatch={() => {}} - errors={{ name: [], 'schedule.interval': [], ruleTypeId: [] }} + errors={{ name: [], 'schedule.interval': [], ruleTypeId: [], actionConnectors: [] }} operation="create" actionTypeRegistry={actionTypeRegistry} ruleTypeRegistry={ruleTypeRegistry} @@ -386,6 +392,7 @@ describe('rule_form', () => { validConsumers={validConsumers} setConsumer={mockSetConsumer} useRuleProducer={useRuleProducer} + selectedConsumer={selectedConsumer} /> ); @@ -666,6 +673,361 @@ describe('rule_form', () => { expect(wrapper.find('[data-test-subj="ruleFormConsumerSelect"]').exists()).toBeFalsy(); }); + + it('Do not show alert query in action when multi consumer rule type does not have a consumer selected', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'alerts', + ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: true, + hasAlertsMappings: true, + }, + ], + ruleTypeModelOverwrite: { + id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(false); + }); + + it('Do not show alert query in action when we do not have hasFieldsForAAD or hasAlertsMappings or belong to security', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'alerts', + ruleTypeId: 'my-rule-type', + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: 'my-rule-type', + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: false, + hasAlertsMappings: false, + }, + ], + ruleTypeModelOverwrite: { + id: 'my-rule-type', + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(false); + }); + + it('Show alert query in action when rule type hasFieldsForAAD', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'alerts', + ruleTypeId: 'my-rule-type', + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: 'my-rule-type', + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: true, + hasAlertsMappings: false, + }, + ], + ruleTypeModelOverwrite: { + id: 'my-rule-type', + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(true); + }); + + it('Show alert query in action when rule type hasAlertsMappings', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'alerts', + ruleTypeId: 'my-rule-type', + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: 'my-rule-type', + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: false, + hasAlertsMappings: true, + }, + ], + ruleTypeModelOverwrite: { + id: 'my-rule-type', + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(true); + }); + + it('Show alert query in action when rule type is from security solution', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'siem', + ruleTypeId: 'my-rule-type', + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: 'my-rule-type', + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: 'siem', + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: false, + hasAlertsMappings: false, + }, + ], + ruleTypeModelOverwrite: { + id: 'my-rule-type', + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(true); + }); + + it('show alert query in action when multi consumer rule type does not have a consumer selected', async () => { + await setup({ + initialRuleOverwrite: { + name: 'Simple rule', + consumer: 'alerts', + ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + schedule: { + interval: '1h', + }, + }, + ruleTypesOverwrite: [ + { + id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + name: 'Threshold Rule', + actionGroups: [ + { + id: 'testActionGroup', + name: 'Test Action Group', + }, + ], + enabledInLicense: true, + defaultActionGroupId: 'threshold.fired', + minimumLicenseRequired: 'basic', + recoveryActionGroup: { id: 'recovered', name: 'Recovered' }, + producer: ALERTS_FEATURE_ID, + authorizedConsumers: { + infrastructure: { read: true, all: true }, + logs: { read: true, all: true }, + }, + actionVariables: { + context: [], + state: [], + params: [], + }, + hasFieldsForAAD: true, + hasAlertsMappings: true, + }, + ], + ruleTypeModelOverwrite: { + id: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID, + iconClass: 'test', + description: 'test', + documentationUrl: null, + validate: (): ValidationResult => { + return { errors: {} }; + }, + ruleParamsExpression: TestExpression, + requiresAppContext: false, + }, + selectedConsumer: 'logs', + }); + + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(wrapper.find(ActionForm).props().hasFieldsForAAD).toEqual(true); + }); }); describe('rule_form create rule non ruleing consumer and producer', () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index c321ba5a01d7..eef420d9e6a1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -153,6 +153,7 @@ interface RuleFormProps> { hideGrouping?: boolean; hideInterval?: boolean; connectorFeatureId?: string; + selectedConsumer?: RuleCreationValidConsumer | null; validConsumers?: RuleCreationValidConsumer[]; onChangeMetaData: (metadata: MetaData) => void; useRuleProducer?: boolean; @@ -176,6 +177,7 @@ export const RuleForm = ({ hideGrouping = false, hideInterval, connectorFeatureId = AlertingConnectorFeatureId, + selectedConsumer, validConsumers, onChangeMetaData, useRuleProducer, @@ -643,6 +645,23 @@ export const RuleForm = ({ } }; + const hasFieldsForAAD = useMemo(() => { + const hasAlertHasData = selectedRuleType + ? selectedRuleType.hasFieldsForAAD || + selectedRuleType.producer === AlertConsumers.SIEM || + selectedRuleType.hasAlertsMappings + : false; + + if (MULTI_CONSUMER_RULE_TYPE_IDS.includes(rule?.ruleTypeId ?? '')) { + return ( + (validConsumers || VALID_CONSUMERS).includes( + selectedConsumer as RuleCreationValidConsumer + ) && hasAlertHasData + ); + } + return hasAlertHasData; + }, [rule?.ruleTypeId, selectedConsumer, selectedRuleType, validConsumers]); + const ruleTypeDetails = ( <> @@ -820,8 +839,12 @@ export const RuleForm = ({ defaultActionGroupId={defaultActionGroupId} hasAlertsMappings={selectedRuleType.hasAlertsMappings} featureId={connectorFeatureId} - producerId={selectedRuleType.producer} - hasFieldsForAAD={selectedRuleType.hasFieldsForAAD} + producerId={ + MULTI_CONSUMER_RULE_TYPE_IDS.includes(rule.ruleTypeId) + ? selectedConsumer ?? rule.consumer + : selectedRuleType.producer + } + hasFieldsForAAD={hasFieldsForAAD} ruleTypeId={rule.ruleTypeId} isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) => isActionGroupDisabledForActionType(selectedRuleType, actionGroupId, actionTypeId) diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_alerts_search_bar.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_alerts_search_bar.tsx index ddeb5e5c4c06..9bbd999aa6a5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/get_alerts_search_bar.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_alerts_search_bar.tsx @@ -6,6 +6,7 @@ */ import { EuiLoadingSpinner } from '@elastic/eui'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import React, { lazy, Suspense } from 'react'; import type { AlertsSearchBarProps } from '../application/sections/alerts_search_bar'; @@ -13,8 +14,12 @@ const AlertsSearchBarLazy: React.FC = lazy( () => import('../application/sections/alerts_search_bar/alerts_search_bar') ); +const queryClient = new QueryClient(); + export const getAlertsSearchBarLazy = (props: AlertsSearchBarProps) => ( }> - + + + ); diff --git a/x-pack/test/accessibility/apps/ml.ts b/x-pack/test/accessibility/apps/ml.ts index dd2fad6de05d..2a6021b7be78 100644 --- a/x-pack/test/accessibility/apps/ml.ts +++ b/x-pack/test/accessibility/apps/ml.ts @@ -50,10 +50,10 @@ export default function ({ getService }: FtrProviderContext) { describe('with data loaded', function () { const dfaOutlierResultsJobId = 'iph_outlier_a11y'; - const ecIndexPattern = 'ft_module_sample_ecommerce'; - const ihpIndexPattern = 'ft_ihp_outlier'; - const egsIndexPattern = 'ft_egs_regression'; - const bmIndexPattern = 'ft_bank_marketing'; + const ecIndexName = 'ft_module_sample_ecommerce'; + const ihpIndexName = 'ft_ihp_outlier'; + const egsIndexName = 'ft_egs_regression'; + const bmIndexName = 'ft_bank_marketing'; const ecExpectedTotalCount = '287'; const dfaOutlierJobType = 'outlier_detection'; @@ -78,10 +78,10 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/module_sample_ecommerce' ); - await ml.testResources.createIndexPatternIfNeeded(ihpIndexPattern); - await ml.testResources.createIndexPatternIfNeeded(egsIndexPattern); - await ml.testResources.createIndexPatternIfNeeded(bmIndexPattern); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await ml.testResources.createDataViewIfNeeded(ihpIndexName); + await ml.testResources.createDataViewIfNeeded(egsIndexName); + await ml.testResources.createDataViewIfNeeded(bmIndexName); + await ml.testResources.createDataViewIfNeeded(ecIndexName, 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunDFAJob( @@ -93,10 +93,10 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.cleanMlIndices(); await ml.api.deleteIndices(`user-${dfaOutlierResultsJobId}`); - await ml.testResources.deleteIndexPatternByTitle(ihpIndexPattern); - await ml.testResources.deleteIndexPatternByTitle(egsIndexPattern); - await ml.testResources.deleteIndexPatternByTitle(bmIndexPattern); - await ml.testResources.deleteIndexPatternByTitle(ecIndexPattern); + await ml.testResources.deleteDataViewByTitle(ihpIndexName); + await ml.testResources.deleteDataViewByTitle(egsIndexName); + await ml.testResources.deleteDataViewByTitle(bmIndexName); + await ml.testResources.deleteDataViewByTitle(ecIndexName); await esArchiver.unload('x-pack/test/functional/es_archives/ml/ihp_outlier'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/egs_regression'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/bm_classification'); @@ -134,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep( 'job creation selects the source data and loads the DFA job wizard page' ); - await ml.jobSourceSelection.selectSourceForAnalyticsJob(ihpIndexPattern); + await ml.jobSourceSelection.selectSourceForAnalyticsJob(ihpIndexName); await ml.dataFrameAnalyticsCreation.assertConfigurationStepActive(); await a11y.testAppSnapshot(); }); @@ -180,7 +180,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataFrameAnalytics(); await ml.dataFrameAnalytics.startAnalyticsCreation(); - await ml.jobSourceSelection.selectSourceForAnalyticsJob(egsIndexPattern); + await ml.jobSourceSelection.selectSourceForAnalyticsJob(egsIndexName); await ml.dataFrameAnalyticsCreation.assertConfigurationStepActive(); await ml.testExecution.logTestStep('selects the regression job type'); await ml.dataFrameAnalyticsCreation.assertJobTypeSelectExists(); @@ -227,7 +227,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataFrameAnalytics(); await ml.dataFrameAnalytics.startAnalyticsCreation(); - await ml.jobSourceSelection.selectSourceForAnalyticsJob(bmIndexPattern); + await ml.jobSourceSelection.selectSourceForAnalyticsJob(bmIndexName); await ml.dataFrameAnalyticsCreation.assertConfigurationStepActive(); await ml.testExecution.logTestStep('selects the classification job type'); await ml.dataFrameAnalyticsCreation.assertJobTypeSelectExists(); @@ -275,12 +275,12 @@ export default function ({ getService }: FtrProviderContext) { }); it('index data visualizer select index pattern page', async () => { - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await a11y.testAppSnapshot(); }); it('index data visualizer page for selected index', async () => { - await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexPattern); + await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexName); await ml.testExecution.logTestStep('should display the time range step'); await ml.dataVisualizerIndexBased.assertTimeRangeSelectorSectionExists(); diff --git a/x-pack/test/accessibility/apps/ml_anomaly_detection.ts b/x-pack/test/accessibility/apps/ml_anomaly_detection.ts index c8cff8616f23..39860093871e 100644 --- a/x-pack/test/accessibility/apps/ml_anomaly_detection.ts +++ b/x-pack/test/accessibility/apps/ml_anomaly_detection.ts @@ -65,10 +65,10 @@ export default function ({ getService }: FtrProviderContext) { const eventDescription = 'calendar_event_a11y'; const filterId = 'filter_a11y'; const filterItems = ['filter_item_a11y']; - const fqIndexPattern = 'ft_farequote'; - const ecIndexPattern = 'ft_module_sample_ecommerce'; + const fqIndexName = 'ft_farequote'; + const ecIndexName = 'ft_module_sample_ecommerce'; - const categorizationIndexPattern = 'ft_categorization_small'; + const categorizationIndexName = 'ft_categorization_small'; const adJobAggAndFieldIdentifier = 'Mean(responsetime)'; const adJobBucketSpan = '30m'; @@ -87,12 +87,12 @@ export default function ({ getService }: FtrProviderContext) { const advancedJobTestData = { suiteTitle: 'with multiple metric detectors and custom datafeed settings', - jobSource: ecIndexPattern, + jobSource: ecIndexName, jobId: `ec_advanced_1_${Date.now()}`, get jobIdClone(): string { return `${this.jobId}_clone`; }, - jobDescription: `Create advanced job from ${ecIndexPattern} dataset with multiple metric detectors and custom datafeed settings`, + jobDescription: `Create advanced job from ${ecIndexName} dataset with multiple metric detectors and custom datafeed settings`, jobGroups: ['automated', 'ecommerce', 'advanced'], get jobGroupsClone(): string[] { return [...this.jobGroups, 'clone']; @@ -149,7 +149,7 @@ export default function ({ getService }: FtrProviderContext) { }; const populationJobTestData = { suiteTitle: 'population job', - jobSource: ecIndexPattern, + jobSource: ecIndexName, jobId: `ec_population_1_${Date.now()}`, get jobIdClone(): string { return `${this.jobId}_clone`; @@ -201,12 +201,9 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/categorization_small' ); - await ml.testResources.createIndexPatternIfNeeded(fqIndexPattern, '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); - await ml.testResources.createIndexPatternIfNeeded( - 'ft_categorization_small', - '@timestamp' - ); + await ml.testResources.createDataViewIfNeeded(fqIndexName, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(ecIndexName, 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_categorization_small', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob( @@ -238,9 +235,9 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.deleteCalendar(calendarId); await ml.api.deleteFilter(filterId); - await ml.testResources.deleteIndexPatternByTitle(fqIndexPattern); - await ml.testResources.deleteIndexPatternByTitle(ecIndexPattern); - await ml.testResources.deleteIndexPatternByTitle(categorizationIndexPattern); + await ml.testResources.deleteDataViewByTitle(fqIndexName); + await ml.testResources.deleteDataViewByTitle(ecIndexName); + await ml.testResources.deleteDataViewByTitle(categorizationIndexName); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/module_sample_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/categorization_small'); @@ -259,7 +256,7 @@ export default function ({ getService }: FtrProviderContext) { }); it('anomaly detection create job select type page', async () => { - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(fqIndexPattern); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(fqIndexName); await a11y.testAppSnapshot(); }); @@ -308,7 +305,7 @@ export default function ({ getService }: FtrProviderContext) { // as the other steps have already been tested for the single metric job await ml.navigation.navigateToAnomalyDetection(); await ml.jobManagement.navigateToNewJobSourceSelection(); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(fqIndexPattern); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(fqIndexName); await ml.jobTypeSelection.selectMultiMetricJob(); await ml.testExecution.logTestStep('job creation set the time range'); await ml.jobWizardCommon.clickUseFullDataButton( @@ -442,7 +439,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToJobManagement(); await ml.jobManagement.navigateToNewJobSourceSelection(); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(ecIndexPattern); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(ecIndexName); await ml.testExecution.logTestStep('job creation loads the population job wizard page'); await ml.jobTypeSelection.selectPopulationJob(); @@ -509,9 +506,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToJobManagement(); await ml.jobManagement.navigateToNewJobSourceSelection(); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob( - categorizationIndexPattern - ); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(categorizationIndexName); await ml.testExecution.logTestStep( 'job creation loads the categorization job wizard page' @@ -566,7 +561,7 @@ export default function ({ getService }: FtrProviderContext) { it('anomaly detection create job from data recognizer module open wizard', async () => { await ml.navigation.navigateToJobManagement(); await ml.jobManagement.navigateToNewJobSourceSelection(); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(ecIndexPattern); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(ecIndexName); await ml.testExecution.logTestStep( `job creation loads the data recognizer job wizard page for the ${adRecognizerJobModuleId} module` ); diff --git a/x-pack/test/accessibility/apps/ml_embeddables_in_dashboard.ts b/x-pack/test/accessibility/apps/ml_embeddables_in_dashboard.ts index 8f8bc67304c0..71933514de00 100644 --- a/x-pack/test/accessibility/apps/ml_embeddables_in_dashboard.ts +++ b/x-pack/test/accessibility/apps/ml_embeddables_in_dashboard.ts @@ -66,7 +66,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.securityCommon.createMlUsers(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); diff --git a/x-pack/test/accessibility/apps/transform.ts b/x-pack/test/accessibility/apps/transform.ts index 9d5257195681..b1228b6c7155 100644 --- a/x-pack/test/accessibility/apps/transform.ts +++ b/x-pack/test/accessibility/apps/transform.ts @@ -42,7 +42,7 @@ export default function ({ getService }: FtrProviderContext) { }); describe('with data loaded', function () { - const ecIndexPattern = 'ft_ecommerce'; + const ecIndexName = 'ft_ecommerce'; const pivotGroupByEntries = [ { @@ -85,7 +85,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await transform.testResources.createDataViewIfNeeded(ecIndexName, 'order_date'); await transform.testResources.setKibanaTimeZoneToUTC(); }); @@ -93,9 +93,9 @@ export default function ({ getService }: FtrProviderContext) { await transform.api.cleanTransformIndices(); await transform.api.deleteIndices(pivotTransformDestinationIndex); await transform.api.deleteIndices(latestTransformDestinationIndex); - await transform.testResources.deleteIndexPatternByTitle(pivotTransformDestinationIndex); - await transform.testResources.deleteIndexPatternByTitle(latestTransformDestinationIndex); - await transform.testResources.deleteIndexPatternByTitle(ecIndexPattern); + await transform.testResources.deleteDataViewByTitle(pivotTransformDestinationIndex); + await transform.testResources.deleteDataViewByTitle(latestTransformDestinationIndex); + await transform.testResources.deleteDataViewByTitle(ecIndexName); await esArchiver.unload('x-pack/test/functional/es_archives/ml/ecommerce'); await transform.testResources.resetKibanaTimeZone(); }); @@ -110,7 +110,7 @@ export default function ({ getService }: FtrProviderContext) { await transform.testExecution.logTestStep( 'transform creation selects the source data and loads the Transform wizard page' ); - await transform.sourceSelection.selectSource(ecIndexPattern); + await transform.sourceSelection.selectSource(ecIndexName); await transform.testExecution.logTestStep( `sets the date picker to the default '15 minutes ago'` @@ -201,7 +201,7 @@ export default function ({ getService }: FtrProviderContext) { await transform.testExecution.logTestStep( 'selects the source data and loads the Transform wizard page' ); - await transform.sourceSelection.selectSource(ecIndexPattern); + await transform.sourceSelection.selectSource(ecIndexName); await transform.testExecution.logTestStep( `sets the date picker to the default '15 minutes ago'` diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index ece39104293a..1475b3aeff8a 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -48,8 +48,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { // CCR tests stay in that order. Their execution fails if rearranged. require.resolve('./apps/remote_clusters'), require.resolve('./apps/snapshot_and_restore'), - // https://github.com/elastic/kibana/issues/153599 - // require.resolve('./apps/cross_cluster_replication'), + require.resolve('./apps/cross_cluster_replication'), require.resolve('./apps/reporting'), require.resolve('./apps/enterprise_search'), // require.resolve('./apps/license_management'), diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts index e3ed2144876a..02983a8607c5 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_fired.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import moment from 'moment'; import { cleanup, generate } from '@kbn/infra-forge'; import { @@ -92,7 +91,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.5], timeSize: 5, @@ -189,7 +187,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [0.5], timeSize: 5, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts index f02eb9568f68..20320dc99dae 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_pct_no_data.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import moment from 'moment'; import { Aggregators, @@ -85,7 +84,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.5], timeSize: 5, @@ -181,7 +179,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [0.5], timeSize: 5, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts index 9929491ea4e0..3312c9e60080 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/avg_us_fired.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import moment from 'moment'; import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace'; import { format } from 'url'; @@ -98,7 +97,7 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, + aggType: 'custom', comparator: Comparator.GT, threshold: [7500000], timeSize: 5, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts index 71f0a1bed860..e2b0e84a5cb0 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts @@ -11,7 +11,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import moment from 'moment'; import { cleanup, generate } from '@kbn/infra-forge'; import { @@ -97,7 +96,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.9], timeSize: 1, @@ -195,7 +193,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.9], timeSize: 1, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts index c2ca213bae98..a602dc901285 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/documents_count_fired.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import moment from 'moment'; import { cleanup, generate } from '@kbn/infra-forge'; import { @@ -92,7 +91,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [2], timeSize: 1, @@ -188,7 +186,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [2], timeSize: 1, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts index 74144e8e7c72..c92971eda405 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule/group_by_fired.ts @@ -7,7 +7,6 @@ import moment from 'moment'; import { cleanup, generate } from '@kbn/infra-forge'; -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -91,7 +90,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT_OR_EQ, threshold: [0.2], timeSize: 1, @@ -214,7 +212,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>=', threshold: [0.2], timeSize: 1, diff --git a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule_data_view.ts b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule_data_view.ts index 0cbb1044f887..6071a6702343 100644 --- a/x-pack/test/alerting_api_integration/observability/custom_threshold_rule_data_view.ts +++ b/x-pack/test/alerting_api_integration/observability/custom_threshold_rule_data_view.ts @@ -6,7 +6,6 @@ */ import expect from '@kbn/expect'; -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -74,7 +73,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [7500000], timeSize: 5, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts index 70cdc0f96dfd..60eb8b6634a3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group2/tests/actions/connector_types/bedrock.ts @@ -13,6 +13,8 @@ import { } from '@kbn/actions-simulators-plugin/server/bedrock_simulation'; import { DEFAULT_TOKEN_LIMIT } from '@kbn/stack-connectors-plugin/common/bedrock/constants'; import { PassThrough } from 'stream'; +import { EventStreamCodec } from '@smithy/eventstream-codec'; +import { fromUtf8, toUtf8 } from '@smithy/util-utf8'; import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; import { getUrlPrefix, ObjectRemover } from '../../../../../common/lib'; @@ -411,8 +413,6 @@ export default function bedrockTest({ getService }: FtrProviderContext) { it('should invoke stream with assistant AI body argument formatted to bedrock expectations', async () => { await new Promise((resolve, reject) => { - let responseBody: string = ''; - const passThrough = new PassThrough(); supertest @@ -434,13 +434,14 @@ export default function bedrockTest({ getService }: FtrProviderContext) { assistantLangChain: false, }) .pipe(passThrough); - + const responseBuffer: Uint8Array[] = []; passThrough.on('data', (chunk) => { - responseBody += chunk.toString(); + responseBuffer.push(chunk); }); passThrough.on('end', () => { - expect(responseBody).to.eql('Hello world, what a unique string!'); + const parsed = parseBedrockBuffer(responseBuffer); + expect(parsed).to.eql('Hello world, what a unique string!'); resolve(); }); }); @@ -517,3 +518,46 @@ export default function bedrockTest({ getService }: FtrProviderContext) { }); }); } + +const parseBedrockBuffer = (chunks: Uint8Array[]): string => { + let bedrockBuffer: Uint8Array = new Uint8Array(0); + + return chunks + .map((chunk) => { + bedrockBuffer = concatChunks(bedrockBuffer, chunk); + let messageLength = getMessageLength(bedrockBuffer); + const buildChunks = []; + while (bedrockBuffer.byteLength > 0 && bedrockBuffer.byteLength >= messageLength) { + const extractedChunk = bedrockBuffer.slice(0, messageLength); + buildChunks.push(extractedChunk); + bedrockBuffer = bedrockBuffer.slice(messageLength); + messageLength = getMessageLength(bedrockBuffer); + } + + const awsDecoder = new EventStreamCodec(toUtf8, fromUtf8); + + return buildChunks + .map((bChunk) => { + const event = awsDecoder.decode(bChunk); + const body = JSON.parse( + Buffer.from(JSON.parse(new TextDecoder().decode(event.body)).bytes, 'base64').toString() + ); + return body.completion; + }) + .join(''); + }) + .join(''); +}; + +function concatChunks(a: Uint8Array, b: Uint8Array): Uint8Array { + const newBuffer = new Uint8Array(a.length + b.length); + newBuffer.set(a); + newBuffer.set(b, a.length); + return newBuffer; +} + +function getMessageLength(buffer: Uint8Array): number { + if (buffer.byteLength === 0) return 0; + const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); + return view.getUint32(0, false); +} diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/create_maintenance_window.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/create_maintenance_window.ts index cf0e2a3dcf6a..05a16cf99284 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/create_maintenance_window.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/create_maintenance_window.ts @@ -25,6 +25,32 @@ export default function createMaintenanceWindowTests({ getService }: FtrProvider tzid: 'UTC', freq: 2, // weekly }, + scoped_query: { + kql: "_id: '1234'", + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + key: 'kibana.alert.action_group', + field: 'kibana.alert.action_group', + params: { + query: 'test', + }, + type: 'phrase', + }, + $state: { + store: 'appState', + }, + query: { + match_phrase: { + 'kibana.alert.action_group': 'test', + }, + }, + }, + ], + }, }; afterEach(() => objectRemover.removeAll()); @@ -69,6 +95,7 @@ export default function createMaintenanceWindowTests({ getService }: FtrProvider expect(response.body.r_rule.dtstart).to.eql(createParams.r_rule.dtstart); expect(response.body.events.length).to.be.greaterThan(0); expect(response.body.status).to.eql('running'); + expect(response.body.scoped_query.kql).to.eql("_id: '1234'"); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); @@ -102,5 +129,19 @@ export default function createMaintenanceWindowTests({ getService }: FtrProvider }) .expect(400); }); + + it('should throw if creating maintenance window with invalid scoped query', async () => { + await supertest + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window`) + .set('kbn-xsrf', 'foo') + .send({ + ...createParams, + scoped_query: { + kql: 'invalid_kql:', + filters: [], + }, + }) + .expect(400); + }); }); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/update_maintenance_window.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/update_maintenance_window.ts index c5d38a1c2a05..8d26f316cb84 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/update_maintenance_window.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group3/tests/maintenance_window/update_maintenance_window.ts @@ -16,6 +16,33 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider const supertest = getService('supertest'); const supertestWithoutAuth = getService('supertestWithoutAuth'); + const scopedQuery = { + kql: "_id: '1234'", + filters: [ + { + meta: { + disabled: false, + negate: false, + alias: null, + key: 'kibana.alert.action_group', + field: 'kibana.alert.action_group', + params: { + query: 'test', + }, + type: 'phrase', + }, + $state: { + store: 'appState', + }, + query: { + match_phrase: { + 'kibana.alert.action_group': 'test', + }, + }, + }, + ], + }; + describe('updateMaintenanceWindow', () => { const objectRemover = new ObjectRemover(supertest); const createParams = { @@ -26,6 +53,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider tzid: 'UTC', freq: 2, // weekly }, + scoped_query: scopedQuery, }; afterEach(() => objectRemover.removeAll()); @@ -82,6 +110,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider expect(response.body.r_rule.dtstart).to.eql(createParams.r_rule.dtstart); expect(response.body.events.length).to.be.greaterThan(0); expect(response.body.status).to.eql('running'); + expect(response.body.scoped_query.kql).to.eql("_id: '1234'"); break; default: throw new Error(`Scenario untested: ${JSON.stringify(scenario)}`); @@ -156,6 +185,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider until: moment.utc().add(1, 'week').toISOString(), }, category_ids: ['management'], + scoped_query: scopedQuery, }) .expect(200); @@ -183,6 +213,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider ...createParams, r_rule: updatedRRule, category_ids: null, + scoped_query: null, }) .expect(200); @@ -194,6 +225,7 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider expect(response.body.data[0].id).to.eql(createdMaintenanceWindow.id); expect(response.body.data[0].r_rule).to.eql(updatedRRule); expect(response.body.data[0].category_ids).to.eql(null); + expect(response.body.data[0].scoped_query).to.eql(null); }); it('should throw if updating maintenance window with invalid category ids', async () => { @@ -230,5 +262,46 @@ export default function updateMaintenanceWindowTests({ getService }: FtrProvider .send({ category_ids: ['something-else'] }) .expect(400); }); + + it('should throw if updating maintenance window with invalid scoped query', async () => { + const { body: createdMaintenanceWindow } = await supertest + .post(`${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window`) + .set('kbn-xsrf', 'foo') + .send({ + title: 'test-maintenance-window', + duration: 60 * 60 * 1000, // 1 hr + r_rule: { + dtstart: new Date().toISOString(), + tzid: 'UTC', + freq: 2, // weekly + count: 1, + }, + scoped_query: scopedQuery, + }) + .expect(200); + + objectRemover.add( + 'space1', + createdMaintenanceWindow.id, + 'rules/maintenance_window', + 'alerting', + true + ); + + await supertest + .post( + `${getUrlPrefix('space1')}/internal/alerting/rules/maintenance_window/${ + createdMaintenanceWindow.id + }` + ) + .set('kbn-xsrf', 'foo') + .send({ + scoped_query: { + kql: 'invalid_kql:', + filters: [], + }, + }) + .expect(400); + }); }); } diff --git a/x-pack/test/api_integration/apis/asset_manager/tests/index.ts b/x-pack/test/api_integration/apis/asset_manager/tests/index.ts index e2ea53990b21..12274a3fc6ab 100644 --- a/x-pack/test/api_integration/apis/asset_manager/tests/index.ts +++ b/x-pack/test/api_integration/apis/asset_manager/tests/index.ts @@ -12,6 +12,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./containers')); loadTestFile(require.resolve('./hosts')); loadTestFile(require.resolve('./services')); + loadTestFile(require.resolve('./pods')); loadTestFile(require.resolve('./sample_assets')); }); } diff --git a/x-pack/test/api_integration/apis/asset_manager/tests/pods.ts b/x-pack/test/api_integration/apis/asset_manager/tests/pods.ts new file mode 100644 index 000000000000..eb88049b6511 --- /dev/null +++ b/x-pack/test/api_integration/apis/asset_manager/tests/pods.ts @@ -0,0 +1,100 @@ +/* + * 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 { timerange, infra } from '@kbn/apm-synthtrace-client'; +import expect from '@kbn/expect'; +import { Asset } from '@kbn/assetManager-plugin/common/types_api'; +import * as routePaths from '@kbn/assetManager-plugin/common/constants_routes'; +import { FtrProviderContext } from '../types'; + +export default function ({ getService }: FtrProviderContext) { + const supertest = getService('supertest'); + const synthtrace = getService('infraSynthtraceEsClient'); + + describe(`GET ${routePaths.GET_PODS}`, () => { + const from = new Date(Date.now() - 1000 * 60 * 2).toISOString(); + const to = new Date().toISOString(); + + beforeEach(async () => { + await synthtrace.clean(); + }); + + it('should return pod assets', async () => { + await synthtrace.index(generatePodsData({ from, to, count: 5 })); + + const response = await supertest + .get(routePaths.GET_PODS) + .query({ + from, + to, + }) + .expect(200); + + expect(response.body).to.have.property('pods'); + expect(response.body.pods.length).to.equal(5); + }); + + it('should return a specific pod asset by EAN', async () => { + await synthtrace.index(generatePodsData({ from, to, count: 5 })); + const testEan = 'pod:pod-uid-1'; + + const response = await supertest + .get(routePaths.GET_PODS) + .query({ + from, + to, + stringFilters: JSON.stringify({ ean: testEan }), + }) + .expect(200); + + expect(response.body).to.have.property('pods'); + expect(response.body.pods.length).to.equal(1); + expect(response.body.pods[0]['asset.ean']).to.equal(testEan); + }); + + it('should return a filtered list of pods assets by ID wildcard pattern', async () => { + await synthtrace.index(generatePodsData({ from, to, count: 15 })); + const testIdPattern = '*id-1*'; + + const response = await supertest + .get(routePaths.GET_PODS) + .query({ + from, + to, + stringFilters: JSON.stringify({ id: testIdPattern }), + }) + .expect(200); + + expect(response.body).to.have.property('pods'); + expect(response.body.pods.length).to.equal(6); + + const ids = response.body.pods.map((result: Asset) => result['asset.id'][0]); + + expect(ids).to.eql([ + 'pod-uid-1', + 'pod-uid-10', + 'pod-uid-11', + 'pod-uid-12', + 'pod-uid-13', + 'pod-uid-14', + ]); + }); + }); +} + +function generatePodsData({ from, to, count = 1 }: { from: string; to: string; count: number }) { + const range = timerange(from, to); + + const pods = Array(count) + .fill(0) + .map((_, idx) => infra.pod(`pod-uid-${idx}`, `node-name-${idx}`)); + + return range + .interval('1m') + .rate(1) + .generator((timestamp) => pods.map((pod) => pod.metrics().timestamp(timestamp))); +} diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js b/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js deleted file mode 100644 index 368272858ea2..000000000000 --- a/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js +++ /dev/null @@ -1,53 +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 { API_BASE_PATH } from './constants'; - -export const registerHelpers = ({ supertest }) => { - const executeActionOnIndices = (index, urlParam, args) => { - const indices = Array.isArray(index) ? index : [index]; - - return supertest - .post(`${API_BASE_PATH}/indices/${urlParam}`) - .set('kbn-xsrf', 'xxx') - .send({ indices, ...args }); - }; - - const closeIndex = (index) => executeActionOnIndices(index, 'close'); - - const openIndex = (index) => executeActionOnIndices(index, 'open'); - - const deleteIndex = (index) => executeActionOnIndices(index, 'delete'); - - const flushIndex = (index) => executeActionOnIndices(index, 'flush'); - - const refreshIndex = (index) => executeActionOnIndices(index, 'refresh'); - - const forceMerge = (index, args) => executeActionOnIndices(index, 'forcemerge', args); - - const unfreeze = (index) => executeActionOnIndices(index, 'unfreeze'); - - const clearCache = (index) => executeActionOnIndices(index, 'clear_cache'); - - const list = () => supertest.get(`${API_BASE_PATH}/indices`); - - const reload = (indexNames) => - supertest.post(`${API_BASE_PATH}/indices/reload`).set('kbn-xsrf', 'xxx').send({ indexNames }); - - return { - closeIndex, - openIndex, - deleteIndex, - flushIndex, - refreshIndex, - forceMerge, - unfreeze, - list, - reload, - clearCache, - }; -}; diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.js b/x-pack/test/api_integration/apis/management/index_management/indices.ts similarity index 75% rename from x-pack/test/api_integration/apis/management/index_management/indices.js rename to x-pack/test/api_integration/apis/management/index_management/indices.ts index 8d012f7a02d4..aa2ff5966c4d 100644 --- a/x-pack/test/api_integration/apis/management/index_management/indices.js +++ b/x-pack/test/api_integration/apis/management/index_management/indices.ts @@ -7,19 +7,13 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; -import { registerHelpers } from './indices.helpers'; import { sortedExpectedIndexKeys } from './constants'; +import { indicesApi } from './lib/indices.api'; +import { indicesHelpers } from './lib/indices.helpers'; +import { FtrProviderContext } from '../../../ftr_provider_context'; -export default function ({ getService }) { - const supertest = getService('supertest'); - - const { - createIndex, - catIndex, - indexStats, - cleanUp: cleanUpEsResources, - } = initElasticsearchHelpers(getService); +export default function ({ getService }: FtrProviderContext) { + const { createIndex, deleteAllIndices, catIndex, indexStats } = indicesHelpers(getService); const { closeIndex, @@ -32,10 +26,10 @@ export default function ({ getService }) { list, reload, clearCache, - } = registerHelpers({ supertest }); + } = indicesApi(getService); describe('indices', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); describe('clear cache', () => { it('should clear the cache on a single index', async () => { @@ -45,9 +39,6 @@ export default function ({ getService }) { }); describe('close', function () { - // The Cloud backend disallows users from closing indices. - this.tags(['skipCloud']); - it('should close an index', async () => { const index = await createIndex(); @@ -68,10 +59,6 @@ export default function ({ getService }) { }); describe('open', function () { - // The Cloud backend disallows users from closing indices, so there's no point testing - // the open behavior. - this.tags(['skipCloud']); - it('should open an index', async () => { const index = await createIndex(); @@ -98,12 +85,12 @@ export default function ({ getService }) { const index = await createIndex(); const { body: indices1 } = await catIndex(undefined, 'i'); - expect(indices1.map((index) => index.i)).to.contain(index); + expect(indices1.map((indexItem) => indexItem.i)).to.contain(index); - await deleteIndex([index]).expect(200); + await deleteIndex(index).expect(200); const { body: indices2 } = await catIndex(undefined, 'i'); - expect(indices2.map((index) => index.i)).not.to.contain(index); + expect(indices2.map((indexItem) => indexItem.i)).not.to.contain(index); }); it('should require index or indices to be provided', async () => { @@ -119,6 +106,7 @@ export default function ({ getService }) { const { body: { indices: indices1 }, } = await indexStats(index, 'flush'); + // @ts-ignore expect(indices1[index].total.flush.total).to.be(0); await flushIndex(index).expect(200); @@ -126,6 +114,7 @@ export default function ({ getService }) { const { body: { indices: indices2 }, } = await indexStats(index, 'flush'); + // @ts-ignore expect(indices2[index].total.flush.total).to.be(1); }); }); @@ -137,6 +126,7 @@ export default function ({ getService }) { const { body: { indices: indices1 }, } = await indexStats(index, 'refresh'); + // @ts-ignore const previousRefreshes = indices1[index].total.refresh.total; await refreshIndex(index).expect(200); @@ -144,6 +134,7 @@ export default function ({ getService }) { const { body: { indices: indices2 }, } = await indexStats(index, 'refresh'); + // @ts-ignore expect(indices2[index].total.refresh.total).to.be(previousRefreshes + 1); }); }); @@ -175,8 +166,6 @@ export default function ({ getService }) { }); describe('list', function () { - this.tags(['skipCloud']); - it('should list all the indices with the expected properties and data enrichers', async function () { // Create an index that we can assert against await createIndex('test_index'); @@ -185,7 +174,7 @@ export default function ({ getService }) { const { body: indices } = await list().expect(200); // Find the "test_index" created to verify expected keys - const indexCreated = indices.find((index) => index.name === 'test_index'); + const indexCreated = indices.find((index: { name: string }) => index.name === 'test_index'); const sortedReceivedKeys = Object.keys(indexCreated).sort(); @@ -194,19 +183,17 @@ export default function ({ getService }) { }); describe('reload', function () { - describe('(not on Cloud)', function () { - this.tags(['skipCloud']); - - it('should list all the indices with the expected properties and data enrichers', async function () { - // create an index to assert against, otherwise the test is flaky - await createIndex('reload-test-index'); - const { body } = await reload().expect(200); - - const indexCreated = body.find((index) => index.name === 'reload-test-index'); - const sortedReceivedKeys = Object.keys(indexCreated).sort(); - expect(sortedReceivedKeys).to.eql(sortedExpectedIndexKeys); - expect(body.length > 1).to.be(true); // to contrast it with the next test - }); + it('should list all the indices with the expected properties and data enrichers', async function () { + // create an index to assert against, otherwise the test is flaky + await createIndex('reload-test-index'); + const { body } = await reload().expect(200); + + const indexCreated = body.find( + (index: { name: string }) => index.name === 'reload-test-index' + ); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + expect(sortedReceivedKeys).to.eql(sortedExpectedIndexKeys); + expect(body.length > 1).to.be(true); // to contrast it with the next test }); it('should allow reloading only certain indices', async () => { diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js index d71085439e86..606fe5a3d8b8 100644 --- a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js +++ b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js @@ -5,8 +5,6 @@ * 2.0. */ -import { getRandomString } from './random'; - /** * Helpers to create and delete indices on the Elasticsearch instance * during our tests. @@ -14,9 +12,7 @@ import { getRandomString } from './random'; */ export const initElasticsearchHelpers = (getService) => { const es = getService('es'); - const esDeleteAllIndices = getService('esDeleteAllIndices'); - let indicesCreated = []; let datastreamCreated = []; let indexTemplatesCreated = []; let componentTemplatesCreated = []; @@ -40,22 +36,6 @@ export const initElasticsearchHelpers = (getService) => { console.log(`[Cleanup error] Error deleting ES resources: ${err.message}`); }); - const createIndex = (index = getRandomString(), body) => { - indicesCreated.push(index); - return es.indices.create({ index, body }).then(() => index); - }; - - const deleteAllIndices = async () => { - await esDeleteAllIndices(indicesCreated); - indicesCreated = []; - }; - - const catIndex = (index, h) => es.cat.indices({ index, format: 'json', h }, { meta: true }); - - const indexStats = (index, metric) => es.indices.stats({ index, metric }, { meta: true }); - - const cleanUp = () => deleteAllIndices(); - const catTemplate = (name) => es.cat.templates({ name, format: 'json' }, { meta: true }); const createIndexTemplate = (indexTemplate, shouldCacheTemplate) => { @@ -103,14 +83,9 @@ export const initElasticsearchHelpers = (getService) => { }); return { - createIndex, - deleteAllIndices, - catIndex, - indexStats, createDatastream, deleteDatastream, cleanupDatastreams, - cleanUp, catTemplate, createIndexTemplate, deleteIndexTemplate, diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts b/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts new file mode 100644 index 000000000000..d75d3ec0527b --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { API_BASE_PATH } from '../constants'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export function indicesApi(getService: FtrProviderContext['getService']) { + const supertest = getService('supertest'); + const executeActionOnIndices = ({ + index, + urlParam, + args, + }: { + index?: string | string[]; + urlParam: string; + args?: any; + }) => { + const indices = Array.isArray(index) ? index : [index]; + + return supertest + .post(`${API_BASE_PATH}/indices/${urlParam}`) + .set('kbn-xsrf', 'xxx') + .send({ indices, ...args }); + }; + + const closeIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'close' }); + + const openIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'open' }); + + const deleteIndex = (index?: string) => executeActionOnIndices({ index, urlParam: 'delete' }); + + const flushIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'flush' }); + + const refreshIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'refresh' }); + + const forceMerge = (index: string, args?: { maxNumSegments: number }) => + executeActionOnIndices({ index, urlParam: 'forcemerge', args }); + + const unfreeze = (index: string) => executeActionOnIndices({ index, urlParam: 'unfreeze' }); + + const clearCache = (index: string) => executeActionOnIndices({ index, urlParam: 'clear_cache' }); + + const list = () => supertest.get(`${API_BASE_PATH}/indices`); + + const reload = (indexNames?: string[]) => + supertest.post(`${API_BASE_PATH}/indices/reload`).set('kbn-xsrf', 'xxx').send({ indexNames }); + + return { + closeIndex, + openIndex, + deleteIndex, + flushIndex, + refreshIndex, + forceMerge, + unfreeze, + list, + reload, + clearCache, + }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts b/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts new file mode 100644 index 000000000000..139e813d84ff --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts @@ -0,0 +1,35 @@ +/* + * 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 { getRandomString } from './random'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export function indicesHelpers(getService: FtrProviderContext['getService']) { + const es = getService('es'); + const esDeleteAllIndices = getService('esDeleteAllIndices'); + + let indicesCreated: string[] = []; + + const createIndex = async (index: string = getRandomString(), mappings?: any) => { + indicesCreated.push(index); + await es.indices.create({ index, mappings }); + return index; + }; + + const deleteAllIndices = async () => { + await esDeleteAllIndices(indicesCreated); + indicesCreated = []; + }; + + const catIndex = (index?: string, h?: any) => + es.cat.indices({ index, format: 'json', h }, { meta: true }); + + const indexStats = (index: string, metric: string) => + es.indices.stats({ index, metric }, { meta: true }); + + return { createIndex, deleteAllIndices, catIndex, indexStats }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/mappings.api.ts b/x-pack/test/api_integration/apis/management/index_management/lib/mappings.api.ts new file mode 100644 index 000000000000..f032f2893e31 --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/lib/mappings.api.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 { API_BASE_PATH } from '../constants'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export function mappingsApi(getService: FtrProviderContext['getService']) { + const supertest = getService('supertest'); + + const getMapping = (index: string) => + supertest + .get(`${API_BASE_PATH}/mapping/${index}`) + .set('kbn-xsrf', 'xxx') + .set('x-elastic-internal-origin', 'xxx'); + + return { + getMapping, + }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/random.js b/x-pack/test/api_integration/apis/management/index_management/lib/random.ts similarity index 100% rename from x-pack/test/api_integration/apis/management/index_management/lib/random.js rename to x-pack/test/api_integration/apis/management/index_management/lib/random.ts diff --git a/x-pack/test/api_integration/apis/management/index_management/mapping.js b/x-pack/test/api_integration/apis/management/index_management/mapping.js deleted file mode 100644 index c18bc4c16352..000000000000 --- a/x-pack/test/api_integration/apis/management/index_management/mapping.js +++ /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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; - -import { initElasticsearchHelpers } from './lib'; -import { registerHelpers } from './mapping.helpers'; - -export default function ({ getService }) { - const supertest = getService('supertest'); - - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); - - const { getIndexMapping } = registerHelpers({ supertest }); - - describe('mapping', () => { - after(() => Promise.all([cleanUpEsResources()])); - - it('should fetch the index mapping', async () => { - const mappings = { - properties: { - total: { type: 'long' }, - tag: { type: 'keyword' }, - createdAt: { type: 'date' }, - }, - }; - const index = await createIndex(undefined, { mappings }); - - const { body } = await getIndexMapping(index).expect(200); - - expect(body.mappings).to.eql(mappings); - }); - }); -} diff --git a/x-pack/test/api_integration/apis/management/index_management/mapping.ts b/x-pack/test/api_integration/apis/management/index_management/mapping.ts new file mode 100644 index 000000000000..5e3ebea13adc --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/mapping.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { mappingsApi } from './lib/mappings.api'; +import { indicesHelpers } from './lib/indices.helpers'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const log = getService('log'); + + const { getMapping } = mappingsApi(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); + + describe('mappings', () => { + let indexName: string; + + const mappings = { + properties: { + total: { type: 'long' }, + tag: { type: 'keyword' }, + createdAt: { type: 'date' }, + }, + }; + + after(async () => await deleteAllIndices()); + + before(async () => { + log.debug('Creating index'); + try { + indexName = await createIndex(undefined, mappings); + } catch (err) { + log.debug('[Setup error] Error creating index'); + throw err; + } + }); + + after(async () => { + try { + await deleteAllIndices(); + } catch (err) { + log.debug('[Cleanup error] Error deleting index'); + throw err; + } + }); + + it('should get the index mappings', async () => { + const { body } = await getMapping(indexName).expect(200); + + expect(body.mappings).to.eql(mappings); + }); + }); +} diff --git a/x-pack/test/api_integration/apis/management/index_management/settings.js b/x-pack/test/api_integration/apis/management/index_management/settings.js index 44ee80aaec7a..fbffc203cff5 100644 --- a/x-pack/test/api_integration/apis/management/index_management/settings.js +++ b/x-pack/test/api_integration/apis/management/index_management/settings.js @@ -7,18 +7,18 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; +import { indicesHelpers } from './lib/indices.helpers'; import { registerHelpers } from './settings.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); const { getIndexSettings, updateIndexSettings } = registerHelpers({ supertest }); describe('settings', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); it('should fetch an index settings', async () => { const index = await createIndex(); diff --git a/x-pack/test/api_integration/apis/management/index_management/stats.js b/x-pack/test/api_integration/apis/management/index_management/stats.js index c673f1046171..782b32a78732 100644 --- a/x-pack/test/api_integration/apis/management/index_management/stats.js +++ b/x-pack/test/api_integration/apis/management/index_management/stats.js @@ -7,18 +7,18 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; +import { indicesHelpers } from './lib/indices.helpers'; import { registerHelpers } from './stats.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); const { getIndexStats } = registerHelpers({ supertest }); describe('stats', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); it('should fetch the index stats', async () => { const index = await createIndex(); diff --git a/x-pack/test/api_integration/apis/management/index_management/templates.js b/x-pack/test/api_integration/apis/management/index_management/templates.js index bb4007852b03..4882ecccf634 100644 --- a/x-pack/test/api_integration/apis/management/index_management/templates.js +++ b/x-pack/test/api_integration/apis/management/index_management/templates.js @@ -13,7 +13,7 @@ import { registerHelpers } from './templates.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { cleanUp: cleanUpEsResources, catTemplate } = initElasticsearchHelpers(getService); + const { catTemplate } = initElasticsearchHelpers(getService); const { getAllTemplates, @@ -27,7 +27,7 @@ export default function ({ getService }) { // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/170980 describe.skip('index templates', () => { - after(() => Promise.all([cleanUpEsResources(), cleanUpTemplates()])); + after(async () => await cleanUpTemplates()); describe('get all', () => { const indexTemplate = getTemplatePayload(`template-${getRandomString()}`, [ diff --git a/x-pack/test/api_integration/apis/ml/data_frame_analytics/delete.ts b/x-pack/test/api_integration/apis/ml/data_frame_analytics/delete.ts index f0e69eddb981..f7e3d1666634 100644 --- a/x-pack/test/api_integration/apis/ml/data_frame_analytics/delete.ts +++ b/x-pack/test/api_integration/apis/ml/data_frame_analytics/delete.ts @@ -42,8 +42,8 @@ export default ({ getService }: FtrProviderContext) => { const testJobConfigs: Array> = [ 'Test delete job only', 'Test delete job and target index', - 'Test delete job and index pattern', - 'Test delete job, target index, and index pattern', + 'Test delete job and data view', + 'Test delete job, target index, and data view', ].map((description, idx) => { const analyticsId = `${jobId}_${idx + 1}`; return { @@ -148,71 +148,71 @@ export default ({ getService }: FtrProviderContext) => { expect(body.analyticsJobDeleted.success).to.eql(true); expect(body.destIndexDeleted.success).to.eql(true); - expect(body.destIndexPatternDeleted.success).to.eql(false); + expect(body.destDataViewDeleted.success).to.eql(false); await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId); await ml.api.assertIndicesNotToExist(destinationIndex); }); }); - describe('with deleteDestIndexPattern setting', function () { + describe('with deleteDestDataView setting', function () { const analyticsId = `${jobId}_3`; const destinationIndex = generateDestinationIndex(analyticsId); before(async () => { - // Mimic real job by creating index pattern after job is created - await ml.testResources.createIndexPatternIfNeeded(destinationIndex); + // Mimic real job by creating data view after job is created + await ml.testResources.createDataViewIfNeeded(destinationIndex); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle(destinationIndex); + await ml.testResources.deleteDataViewByTitle(destinationIndex); }); - it('should delete job and index pattern by id', async () => { + it('should delete job and data view by id', async () => { const { body, status } = await supertest .delete(`/internal/ml/data_frame/analytics/${analyticsId}`) - .query({ deleteDestIndexPattern: true }) + .query({ deleteDestDataView: true }) .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) .set(getCommonRequestHeader('1')); ml.api.assertResponseStatusCode(200, status, body); expect(body.analyticsJobDeleted.success).to.eql(true); expect(body.destIndexDeleted.success).to.eql(false); - expect(body.destIndexPatternDeleted.success).to.eql(true); + expect(body.destDataViewDeleted.success).to.eql(true); await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId); - await ml.testResources.assertIndexPatternNotExist(destinationIndex); + await ml.testResources.assertDataViewNotExist(destinationIndex); }); }); - describe('with deleteDestIndex & deleteDestIndexPattern setting', function () { + describe('with deleteDestIndex & deleteDestDataView setting', function () { const analyticsId = `${jobId}_4`; const destinationIndex = generateDestinationIndex(analyticsId); before(async () => { - // Mimic real job by creating target index & index pattern after DFA job is created + // Mimic real job by creating target index & data view after DFA job is created await ml.api.createIndex(destinationIndex); await ml.api.assertIndicesExist(destinationIndex); - await ml.testResources.createIndexPatternIfNeeded(destinationIndex); + await ml.testResources.createDataViewIfNeeded(destinationIndex); }); after(async () => { await ml.api.deleteIndices(destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(destinationIndex); + await ml.testResources.deleteDataViewByTitle(destinationIndex); }); - it('should delete job, target index, and index pattern by id', async () => { + it('should delete job, target index, and data view by id', async () => { const { body, status } = await supertest .delete(`/internal/ml/data_frame/analytics/${analyticsId}`) - .query({ deleteDestIndex: true, deleteDestIndexPattern: true }) + .query({ deleteDestIndex: true, deleteDestDataView: true }) .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) .set(getCommonRequestHeader('1')); ml.api.assertResponseStatusCode(200, status, body); expect(body.analyticsJobDeleted.success).to.eql(true); expect(body.destIndexDeleted.success).to.eql(true); - expect(body.destIndexPatternDeleted.success).to.eql(true); + expect(body.destDataViewDeleted.success).to.eql(true); await ml.api.waitForDataFrameAnalyticsJobNotToExist(analyticsId); await ml.api.assertIndicesNotToExist(destinationIndex); - await ml.testResources.assertIndexPatternNotExist(destinationIndex); + await ml.testResources.assertDataViewNotExist(destinationIndex); }); }); }); diff --git a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts index 4f759a1c5a93..eff763fbcfcd 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/close_jobs.ts @@ -46,12 +46,12 @@ export default ({ getService }: FtrProviderContext) => { describe('close_jobs', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); beforeEach(async () => { diff --git a/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts b/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts index f45f7052b65c..610d5be81278 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/jobs_exist.ts @@ -83,13 +83,13 @@ export default ({ getService }: FtrProviderContext) => { describe('jobs_exist', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); }); after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('sets up jobs', async () => { diff --git a/x-pack/test/api_integration/apis/ml/jobs/reset.ts b/x-pack/test/api_integration/apis/ml/jobs/reset.ts index 0b69097a907e..2e193816efb9 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/reset.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/reset.ts @@ -55,12 +55,12 @@ export default ({ getService }: FtrProviderContext) => { describe('reset_jobs', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); beforeEach(async () => { diff --git a/x-pack/test/api_integration/apis/ml/modules/jobs_exist.ts b/x-pack/test/api_integration/apis/ml/modules/jobs_exist.ts index 0f59baa11d13..22176a6e5c7f 100644 --- a/x-pack/test/api_integration/apis/ml/modules/jobs_exist.ts +++ b/x-pack/test/api_integration/apis/ml/modules/jobs_exist.ts @@ -39,12 +39,12 @@ export default ({ getService }: FtrProviderContext) => { await ml.testResources.setKibanaTimeZoneToUTC(); await esArchiver.loadIfNeeded(sourceDataArchive); // create data view in default space - await ml.testResources.createIndexPatternIfNeeded( + await ml.testResources.createDataViewIfNeeded( moduleInfo.dataView.name, moduleInfo.dataView.timeField ); // create data view in idSpace1 - await ml.testResources.createIndexPatternIfNeeded( + await ml.testResources.createDataViewIfNeeded( moduleInfo.dataView.name, moduleInfo.dataView.timeField, idSpace1 @@ -57,8 +57,8 @@ export default ({ getService }: FtrProviderContext) => { after(async () => { // delete all data views in all spaces - await ml.testResources.deleteIndexPatternByTitle(moduleInfo.dataView.name); - await ml.testResources.deleteIndexPatternByTitle(moduleInfo.dataView.name, idSpace1); + await ml.testResources.deleteDataViewByTitle(moduleInfo.dataView.name); + await ml.testResources.deleteDataViewByTitle(moduleInfo.dataView.name, idSpace1); }); it('should find jobs installed by module without prefix', async () => { diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts index 1eb327c897b0..27d6d048e3f8 100644 --- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts @@ -710,7 +710,7 @@ export default ({ getService }: FtrProviderContext) => { describe('sets up module data', function () { before(async () => { await esArchiver.loadIfNeeded(testData.sourceDataArchive); - await ml.testResources.createIndexPatternIfNeeded( + await ml.testResources.createDataViewIfNeeded( testData.indexPattern.name, testData.indexPattern.timeField ); @@ -730,7 +730,7 @@ export default ({ getService }: FtrProviderContext) => { await ml.api.deleteAnomalyDetectionJobES(job.jobId); } await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle(testData.indexPattern.name); + await ml.testResources.deleteDataViewByTitle(testData.indexPattern.name); }); it(testData.testTitleSuffix, async () => { @@ -864,7 +864,7 @@ export default ({ getService }: FtrProviderContext) => { await esArchiver.loadIfNeeded(testData.sourceDataArchive!); } if (testData.hasOwnProperty('indexPattern')) { - await ml.testResources.createIndexPatternIfNeeded( + await ml.testResources.createDataViewIfNeeded( testData.indexPattern!.name as string, testData.indexPattern!.timeField as string ); @@ -874,7 +874,7 @@ export default ({ getService }: FtrProviderContext) => { after(async () => { await ml.api.cleanMlIndices(); if (testData.hasOwnProperty('indexPattern')) { - await ml.testResources.deleteIndexPatternByTitle(testData.indexPattern!.name); + await ml.testResources.deleteDataViewByTitle(testData.indexPattern!.name); } }); diff --git a/x-pack/test/api_integration/apis/ml/results/get_categorizer_stats.ts b/x-pack/test/api_integration/apis/ml/results/get_categorizer_stats.ts index 9c0add9e6be9..87154beb07ef 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_categorizer_stats.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_categorizer_stats.ts @@ -60,7 +60,7 @@ export default ({ getService }: FtrProviderContext) => { }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_logs'); await ml.api.cleanMlIndices(); }); diff --git a/x-pack/test/api_integration/apis/ml/results/get_stopped_partitions.ts b/x-pack/test/api_integration/apis/ml/results/get_stopped_partitions.ts index d72214128232..3dc4686102c3 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_stopped_partitions.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_stopped_partitions.ts @@ -96,7 +96,7 @@ export default ({ getService }: FtrProviderContext) => { }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_logs'); await ml.api.cleanMlIndices(); }); diff --git a/x-pack/test/api_integration/apis/transform/delete_transforms.ts b/x-pack/test/api_integration/apis/transform/delete_transforms.ts index faf18e5d610e..a064fd28b214 100644 --- a/x-pack/test/api_integration/apis/transform/delete_transforms.ts +++ b/x-pack/test/api_integration/apis/transform/delete_transforms.ts @@ -232,12 +232,12 @@ export default ({ getService }: FtrProviderContext) => { before(async () => { await createTransform(transformId); await transform.api.createIndices(destinationIndex); - await transform.testResources.createIndexPatternIfNeeded(destinationIndex); + await transform.testResources.createDataViewIfNeeded(destinationIndex); }); after(async () => { await transform.api.deleteIndices(destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(destinationIndex); + await transform.testResources.deleteDataViewByTitle(destinationIndex); }); it('should delete transform and destination index pattern', async () => { @@ -261,7 +261,7 @@ export default ({ getService }: FtrProviderContext) => { expect(body[transformId].destDataViewDeleted.success).to.eql(true); await transform.api.waitForTransformNotToExist(transformId); await transform.api.waitForIndicesToExist(destinationIndex); - await transform.testResources.assertIndexPatternNotExist(destinationIndex); + await transform.testResources.assertDataViewNotExist(destinationIndex); }); }); @@ -272,12 +272,12 @@ export default ({ getService }: FtrProviderContext) => { before(async () => { await createTransform(transformId); await transform.api.createIndices(destinationIndex); - await transform.testResources.createIndexPatternIfNeeded(destinationIndex); + await transform.testResources.createDataViewIfNeeded(destinationIndex); }); after(async () => { await transform.api.deleteIndices(destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(destinationIndex); + await transform.testResources.deleteDataViewByTitle(destinationIndex); }); it('should delete transform, destination index, & destination index pattern', async () => { @@ -301,7 +301,7 @@ export default ({ getService }: FtrProviderContext) => { expect(body[transformId].destDataViewDeleted.success).to.eql(true); await transform.api.waitForTransformNotToExist(transformId); await transform.api.waitForIndicesNotToExist(destinationIndex); - await transform.testResources.assertIndexPatternNotExist(destinationIndex); + await transform.testResources.assertDataViewNotExist(destinationIndex); }); }); }); diff --git a/x-pack/test/api_integration/apis/transform/transforms_create.ts b/x-pack/test/api_integration/apis/transform/transforms_create.ts index 84617f6990e3..a41a7f3c5709 100644 --- a/x-pack/test/api_integration/apis/transform/transforms_create.ts +++ b/x-pack/test/api_integration/apis/transform/transforms_create.ts @@ -84,7 +84,7 @@ export default ({ getService }: FtrProviderContext) => { }, ]); - await transform.testResources.deleteIndexPatternByTitle(destinationIndex); + await transform.testResources.deleteDataViewByTitle(destinationIndex); }); it('should create a transform with data view and time field', async () => { @@ -118,7 +118,7 @@ export default ({ getService }: FtrProviderContext) => { }, ]); - await transform.testResources.deleteIndexPatternByTitle(destinationIndex); + await transform.testResources.deleteDataViewByTitle(destinationIndex); }); it('should not allow pivot and latest configs in same transform', async () => { diff --git a/x-pack/test/api_integration/apis/watcher/watcher.ts b/x-pack/test/api_integration/apis/watcher/watcher.ts index 734b6c8c6212..a5d26c98dfe7 100644 --- a/x-pack/test/api_integration/apis/watcher/watcher.ts +++ b/x-pack/test/api_integration/apis/watcher/watcher.ts @@ -17,7 +17,7 @@ export default function ({ getService }: FtrProviderContext) { describe('watcher', () => { before(async () => { try { - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); } catch (error) { log.debug('[Setup error] Error creating index pattern'); throw error; @@ -26,7 +26,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { try { - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); } catch (error) { log.debug('[Cleanup error] Error deleting index pattern'); throw error; diff --git a/x-pack/test/api_integration/services/index.ts b/x-pack/test/api_integration/services/index.ts index 6ef3e393a86e..1f8d4576d908 100644 --- a/x-pack/test/api_integration/services/index.ts +++ b/x-pack/test/api_integration/services/index.ts @@ -21,6 +21,7 @@ import { MachineLearningProvider } from './ml'; import { IngestManagerProvider } from '../../common/services/ingest_manager'; import { TransformProvider } from './transform'; import { IngestPipelinesProvider } from './ingest_pipelines'; +import { IndexManagementProvider } from './index_management'; export const services = { ...commonServices, @@ -37,4 +38,5 @@ export const services = { ingestManager: IngestManagerProvider, transform: TransformProvider, ingestPipelines: IngestPipelinesProvider, + indexManagement: IndexManagementProvider, }; diff --git a/x-pack/test/api_integration/services/index_management.ts b/x-pack/test/api_integration/services/index_management.ts new file mode 100644 index 000000000000..44d33752e414 --- /dev/null +++ b/x-pack/test/api_integration/services/index_management.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 { FtrProviderContext } from '../ftr_provider_context'; +import { indicesApi } from '../apis/management/index_management/lib/indices.api'; +import { mappingsApi } from '../apis/management/index_management/lib/mappings.api'; +import { indicesHelpers } from '../apis/management/index_management/lib/indices.helpers'; + +export function IndexManagementProvider({ getService }: FtrProviderContext) { + return { + indices: { + api: indicesApi(getService), + helpers: indicesHelpers(getService), + }, + mappings: { + api: mappingsApi(getService), + }, + }; +} diff --git a/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts b/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts index c07d6dc6c0f5..b37d68fe936a 100644 --- a/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/get_service_node_metadata.spec.ts @@ -7,6 +7,8 @@ import expect from '@kbn/expect'; import { apm, timerange } from '@kbn/apm-synthtrace-client'; +import { ApmDocumentType } from '@kbn/apm-plugin/common/document_type'; +import { RollupInterval } from '@kbn/apm-plugin/common/rollup'; import { FtrProviderContext } from '../../common/ftr_provider_context'; export default function ApiTest({ getService }: FtrProviderContext) { @@ -29,6 +31,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { end: new Date(end).toISOString(), kuery: '', environment: 'production', + documentType: ApmDocumentType.TransactionMetric, + rollupInterval: RollupInterval.OneMinute, }, }, }); diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_old_data.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_old_data.ts index fc12d593333b..a8cda10482e2 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/findings_old_data.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/findings_old_data.ts @@ -55,7 +55,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }, ]; - describe('Old Data', function () { + describe.skip('Old Data', function () { this.tags(['cloud_security_posture_findings']); let findings: typeof pageObjects.findings; diff --git a/x-pack/test/dataset_quality_api_integration/common/config.ts b/x-pack/test/dataset_quality_api_integration/common/config.ts index 7a0c7c08fb2f..e10ad4273fe7 100644 --- a/x-pack/test/dataset_quality_api_integration/common/config.ts +++ b/x-pack/test/dataset_quality_api_integration/common/config.ts @@ -13,6 +13,7 @@ import { createDatasetQualityUsers } from '@kbn/dataset-quality-plugin/server/te import { FtrConfigProviderContext } from '@kbn/test'; import supertest from 'supertest'; import { format, UrlObject } from 'url'; +import { createLogger, LogLevel, LogsSynthtraceEsClient } from '@kbn/apm-synthtrace'; import { FtrProviderContext, InheritedFtrProviderContext, @@ -64,6 +65,9 @@ export interface CreateTest { services: InheritedServices & { datasetQualityFtrConfig: () => DatasetQualityFtrConfig; registry: ({ getService }: FtrProviderContext) => ReturnType; + logSynthtraceEsClient: ( + context: InheritedFtrProviderContext + ) => Promise; datasetQualityApiClient: (context: InheritedFtrProviderContext) => DatasetQualityApiClient; }; junit: { reportName: string }; @@ -95,6 +99,12 @@ export function createTestConfig( ...services, datasetQualityFtrConfig: () => config, registry: RegistryProvider, + logSynthtraceEsClient: (context: InheritedFtrProviderContext) => + new LogsSynthtraceEsClient({ + client: context.getService('es'), + logger: createLogger(LogLevel.info), + refreshAfterIndex: true, + }), datasetQualityApiClient: async (_: InheritedFtrProviderContext) => { const { username, password } = servers.kibana; const esUrl = format(esServer); diff --git a/x-pack/test/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts b/x-pack/test/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts index d28ddb5f0496..79818e970a2a 100644 --- a/x-pack/test/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts +++ b/x-pack/test/dataset_quality_api_integration/common/dataset_quality_api_supertest.ts @@ -10,10 +10,7 @@ import supertest from 'supertest'; import request from 'superagent'; import type { APIEndpoint } from '@kbn/dataset-quality-plugin/server/routes'; import { formatRequest } from '@kbn/server-route-repository'; -import { - APIClientRequestParamsOf, - APIReturnType, -} from '@kbn/dataset-quality-plugin/public/services/rest/create_call_dataset_quality_api'; +import type { APIClientRequestParamsOf, APIReturnType } from '@kbn/dataset-quality-plugin/common'; export function createDatasetQualityApiClient(st: supertest.SuperTest) { return async ( diff --git a/x-pack/test/dataset_quality_api_integration/tests/data_streams.spec.ts b/x-pack/test/dataset_quality_api_integration/tests/data_streams.spec.ts index cd236c109c66..6d11326bf213 100644 --- a/x-pack/test/dataset_quality_api_integration/tests/data_streams.spec.ts +++ b/x-pack/test/dataset_quality_api_integration/tests/data_streams.spec.ts @@ -5,15 +5,19 @@ * 2.0. */ +import { log, timerange } from '@kbn/apm-synthtrace-client'; import expect from '@kbn/expect'; import { DatasetQualityApiClientKey } from '../common/config'; import { DatasetQualityApiError } from '../common/dataset_quality_api_supertest'; import { FtrProviderContext } from '../common/ftr_provider_context'; import { expectToReject } from '../utils'; +import { cleanLogIndexTemplate, addIntegrationToLogIndexTemplate } from './es_utils'; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); + const synthtrace = getService('logSynthtraceEsClient'); const datasetQualityApiClient = getService('datasetQualityApiClient'); + const es = getService('es'); async function callApiAs(user: DatasetQualityApiClientKey) { return await datasetQualityApiClient[user]({ @@ -21,7 +25,6 @@ export default function ApiTest({ getService }: FtrProviderContext) { params: { query: { type: 'logs', - sortOrder: 'asc', }, }, }); @@ -40,10 +43,67 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); describe('when required privileges are set', () => { - it('returns true when user has logMonitoring privileges', async () => { - const privileges = await callApiAs('datasetQualityLogsUser'); + describe('and uncategorized datastreams', () => { + const integration = 'my-custom-integration'; - expect(privileges.body.items.length).to.be(0); + before(async () => { + await addIntegrationToLogIndexTemplate({ esClient: es, name: integration }); + + await synthtrace.index([ + timerange('2023-11-20T15:00:00.000Z', '2023-11-20T15:01:00.000Z') + .interval('1m') + .rate(1) + .generator((timestamp) => + log.create().message('This is a log message').timestamp(timestamp).defaults({ + 'log.file.path': '/my-service.log', + }) + ), + ]); + }); + + it('returns stats correctly', async () => { + const stats = await callApiAs('datasetQualityLogsUser'); + + expect(stats.body.dataStreamsStats.length).to.be(1); + expect(stats.body.dataStreamsStats[0].integration).to.be(integration); + expect(stats.body.dataStreamsStats[0].size).not.empty(); + expect(stats.body.dataStreamsStats[0].size_bytes).greaterThan(0); + expect(stats.body.dataStreamsStats[0].last_activity).greaterThan(0); + }); + + after(async () => { + await synthtrace.clean(); + await cleanLogIndexTemplate({ esClient: es }); + }); + }); + + describe('and categorized datastreams', () => { + before(async () => { + await synthtrace.index([ + timerange('2023-11-20T15:00:00.000Z', '2023-11-20T15:01:00.000Z') + .interval('1m') + .rate(1) + .generator((timestamp) => + log.create().message('This is a log message').timestamp(timestamp).defaults({ + 'log.file.path': '/my-service.log', + }) + ), + ]); + }); + + it('returns stats correctly', async () => { + const stats = await callApiAs('datasetQualityLogsUser'); + + expect(stats.body.dataStreamsStats.length).to.be(1); + expect(stats.body.dataStreamsStats[0].integration).not.ok(); + expect(stats.body.dataStreamsStats[0].size).not.empty(); + expect(stats.body.dataStreamsStats[0].size_bytes).greaterThan(0); + expect(stats.body.dataStreamsStats[0].last_activity).greaterThan(0); + }); + + after(async () => { + await synthtrace.clean(); + }); }); }); }); diff --git a/x-pack/test/dataset_quality_api_integration/tests/es_utils.ts b/x-pack/test/dataset_quality_api_integration/tests/es_utils.ts new file mode 100644 index 000000000000..607522089952 --- /dev/null +++ b/x-pack/test/dataset_quality_api_integration/tests/es_utils.ts @@ -0,0 +1,54 @@ +/* + * 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 { Client } from '@elastic/elasticsearch'; + +export async function addIntegrationToLogIndexTemplate({ + esClient, + name, + managedBy = 'fleet', +}: { + esClient: Client; + name: string; + managedBy?: string; +}) { + const { index_templates: indexTemplates } = await esClient.indices.getIndexTemplate({ + name: 'logs', + }); + + await esClient.indices.putIndexTemplate({ + name: 'logs', + body: { + ...indexTemplates[0].index_template, + _meta: { + ...indexTemplates[0].index_template._meta, + package: { + name, + }, + managed_by: managedBy, + }, + }, + }); +} + +export async function cleanLogIndexTemplate({ esClient }: { esClient: Client }) { + const { index_templates: indexTemplates } = await esClient.indices.getIndexTemplate({ + name: 'logs', + }); + + await esClient.indices.putIndexTemplate({ + name: 'logs', + body: { + ...indexTemplates[0].index_template, + _meta: { + ...indexTemplates[0].index_template._meta, + package: undefined, + managed_by: undefined, + }, + }, + }); +} diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/index.ts b/x-pack/test/detection_engine_api_integration/basic/tests/index.ts index 315a06043684..5b3449707d38 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/index.ts +++ b/x-pack/test/detection_engine_api_integration/basic/tests/index.ts @@ -10,7 +10,6 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; // eslint-disable-next-line import/no-default-export export default ({ loadTestFile }: FtrProviderContext): void => { describe('detection engine api basic license', function () { - loadTestFile(require.resolve('./create_rules')); loadTestFile(require.resolve('./create_rules_bulk')); loadTestFile(require.resolve('./delete_rules')); loadTestFile(require.resolve('./delete_rules_bulk')); @@ -22,8 +21,6 @@ export default ({ loadTestFile }: FtrProviderContext): void => { loadTestFile(require.resolve('./update_rules_bulk')); loadTestFile(require.resolve('./patch_rules_bulk')); loadTestFile(require.resolve('./patch_rules')); - loadTestFile(require.resolve('./query_signals')); - loadTestFile(require.resolve('./open_close_signals')); loadTestFile(require.resolve('./import_timelines')); loadTestFile(require.resolve('./coverage_overview')); }); diff --git a/x-pack/test/detection_engine_api_integration/utils/index.ts b/x-pack/test/detection_engine_api_integration/utils/index.ts index a1373f03a181..d3fd910681a3 100644 --- a/x-pack/test/detection_engine_api_integration/utils/index.ts +++ b/x-pack/test/detection_engine_api_integration/utils/index.ts @@ -44,7 +44,6 @@ export * from './get_rule_for_signal_testing_with_timestamp_override'; export * from './get_rule_with_web_hook_action'; export * from './get_rule_with_legacy_investigation_fields'; export * from './get_saved_query_rule_for_signal_testing'; -export * from './get_signal_status'; export * from './get_signals_by_id'; export * from './get_signals_by_ids'; export * from './get_signals_by_rule_ids'; diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_dynamic_template_metric.ts b/x-pack/test/fleet_api_integration/apis/epm/install_dynamic_template_metric.ts index cc2bb4ebd858..9bcf3fc673ea 100644 --- a/x-pack/test/fleet_api_integration/apis/epm/install_dynamic_template_metric.ts +++ b/x-pack/test/fleet_api_integration/apis/epm/install_dynamic_template_metric.ts @@ -24,14 +24,14 @@ export default function (providerContext: FtrProviderContext) { setupFleetAndAgents(providerContext); after(async () => { - await deletePackage('istio', '0.3.3'); + await deletePackage('no_tsdb_to_tsdb', '0.2.0'); }); it('should install with metric_type added as time_series_metric', async function () { - const templateName = 'metrics-istio.istiod_metrics@package'; + const templateName = 'metrics-no_tsdb_to_tsdb.test@package'; await supertest - .post(`/api/fleet/epm/packages/istio/0.3.3`) + .post(`/api/fleet/epm/packages/no_tsdb_to_tsdb/0.2.0`) .set('kbn-xsrf', 'xxxx') .send({ force: true }) .expect(200); @@ -46,7 +46,7 @@ export default function (providerContext: FtrProviderContext) { const template = resp.component_templates[0].component_template; const dynamicTemplates = template.template.mappings.dynamic_templates; - const mappingName = 'istio.istiod.metrics.*.counter'; + const mappingName = 'test.metrics.*.counter'; const counter = dynamicTemplates.find((tmpl: any) => Object.keys(tmpl)[0] === mappingName); expect(counter[mappingName].mapping.time_series_metric).to.eql('counter'); diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/no_tsdb_to_tsdb/0.2.0/data_stream/test/fields/fields.yml b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/no_tsdb_to_tsdb/0.2.0/data_stream/test/fields/fields.yml index e1fd2db653ef..6cc90f2148d1 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/no_tsdb_to_tsdb/0.2.0/data_stream/test/fields/fields.yml +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/no_tsdb_to_tsdb/0.2.0/data_stream/test/fields/fields.yml @@ -20,3 +20,10 @@ - name: 'some_metric_field' type: integer metric_type: gauge +- name: test.metrics.*.counter + type: object + object_type: double + object_type_mapping_type: "*" + metric_type: counter + description: > + Istiod counter metric diff --git a/x-pack/test/functional/apps/aiops/change_point_detection.ts b/x-pack/test/functional/apps/aiops/change_point_detection.ts index f643de514c0c..25ed676e9429 100644 --- a/x-pack/test/functional/apps/aiops/change_point_detection.ts +++ b/x-pack/test/functional/apps/aiops/change_point_detection.ts @@ -19,20 +19,20 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('change point detection', async function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it(`loads the change point detection page`, async () => { // Start navigation from the base of the ML app. await ml.navigation.navigateToMl(); await elasticChart.setNewChartUiDebugFlag(true); - await aiops.changePointDetectionPage.navigateToIndexPatternSelection(); + await aiops.changePointDetectionPage.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForChangePointDetection('ft_ecommerce'); await aiops.changePointDetectionPage.assertChangePointDetectionPageExists(); }); diff --git a/x-pack/test/functional/apps/aiops/log_pattern_analysis.ts b/x-pack/test/functional/apps/aiops/log_pattern_analysis.ts index 921d02c8c0c6..6ea8a1d4abc3 100644 --- a/x-pack/test/functional/apps/aiops/log_pattern_analysis.ts +++ b/x-pack/test/functional/apps/aiops/log_pattern_analysis.ts @@ -36,20 +36,20 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); - await ml.testResources.createIndexPatternIfNeeded('logstash-*', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('logstash-*', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('logstash-*'); + await ml.testResources.deleteDataViewByTitle('logstash-*'); }); it(`loads the log pattern analysis page and filters in patterns in discover`, async () => { // Start navigation from the base of the ML app. await ml.navigation.navigateToMl(); await elasticChart.setNewChartUiDebugFlag(true); - await aiops.logPatternAnalysisPage.navigateToIndexPatternSelection(); + await aiops.logPatternAnalysisPage.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForLogPatternAnalysisDetection('logstash-*'); await aiops.logPatternAnalysisPage.assertLogPatternAnalysisPageExists(); @@ -76,7 +76,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // Start navigation from the base of the ML app. await ml.navigation.navigateToMl(); await elasticChart.setNewChartUiDebugFlag(true); - await aiops.logPatternAnalysisPage.navigateToIndexPatternSelection(); + await aiops.logPatternAnalysisPage.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForLogPatternAnalysisDetection('logstash-*'); await aiops.logPatternAnalysisPage.assertLogPatternAnalysisPageExists(); diff --git a/x-pack/test/functional/apps/aiops/log_pattern_analysis_in_discover.ts b/x-pack/test/functional/apps/aiops/log_pattern_analysis_in_discover.ts index 9845cf0a5180..403bbe6382f6 100644 --- a/x-pack/test/functional/apps/aiops/log_pattern_analysis_in_discover.ts +++ b/x-pack/test/functional/apps/aiops/log_pattern_analysis_in_discover.ts @@ -36,13 +36,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/logstash_functional'); - await ml.testResources.createIndexPatternIfNeeded('logstash-*', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('logstash-*', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle('logstash-*'); + await ml.testResources.deleteDataViewByTitle('logstash-*'); }); it(`loads the log pattern analysis flyout and shows patterns in discover`, async () => { diff --git a/x-pack/test/functional/apps/aiops/log_rate_analysis.ts b/x-pack/test/functional/apps/aiops/log_rate_analysis.ts index 8e33b4b1c8e4..68c9256b382d 100644 --- a/x-pack/test/functional/apps/aiops/log_rate_analysis.ts +++ b/x-pack/test/functional/apps/aiops/log_rate_analysis.ts @@ -15,6 +15,7 @@ import { logRateAnalysisTestData } from './log_rate_analysis_test_data'; export default function ({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'console', 'header', 'home', 'security']); + const browser = getService('browser'); const elasticChart = getService('elasticChart'); const aiops = getService('aiops'); @@ -28,7 +29,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await aiops.logRateAnalysisPage.navigateToIndexPatternSelection(); + await aiops.logRateAnalysisPage.navigateToDataViewSelection(); await ml.testExecution.logTestStep(`${testData.suiteTitle} loads the log rate analysis page`); await ml.jobSourceSelection.selectSourceForLogRateAnalysis(testData.sourceIndexOrSavedSearch); @@ -147,6 +148,12 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await aiops.logRateAnalysisPage.clickRerunAnalysisButton(true); } + // Wait for the analysis to finish + await aiops.logRateAnalysisPage.assertAnalysisComplete(testData.analysisType); + + // At this stage the baseline and deviation brush position should be stored in + // the url state and a full browser refresh should restore the analysis. + await browser.refresh(); await aiops.logRateAnalysisPage.assertAnalysisComplete(testData.analysisType); // The group switch should be disabled by default @@ -234,7 +241,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { before(async () => { await aiops.logRateAnalysisDataGenerator.generateData(testData.dataGenerator); - await ml.testResources.createIndexPatternIfNeeded( + await ml.testResources.createDataViewIfNeeded( testData.sourceIndexOrSavedSearch, '@timestamp' ); @@ -260,7 +267,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { after(async () => { await elasticChart.setNewChartUiDebugFlag(false); if (testData.dataGenerator !== 'kibana_sample_data_logs') { - await ml.testResources.deleteIndexPatternByTitle(testData.sourceIndexOrSavedSearch); + await ml.testResources.deleteDataViewByTitle(testData.sourceIndexOrSavedSearch); } await aiops.logRateAnalysisDataGenerator.removeGeneratedData(testData.dataGenerator); }); diff --git a/x-pack/test/functional/apps/discover/visualize_field.ts b/x-pack/test/functional/apps/discover/visualize_field.ts index a61a2abba187..428ef13c3486 100644 --- a/x-pack/test/functional/apps/discover/visualize_field.ts +++ b/x-pack/test/functional/apps/discover/visualize_field.ts @@ -255,5 +255,76 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const data = await PageObjects.lens.getCurrentChartDebugStateForVizType('xyVisChart'); assertMatchesExpectedData(data!); }); + + it('should allow editing the query in the dashboard', async () => { + await PageObjects.discover.selectTextBaseLang(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await monacoEditor.setCodeEditorValue('from logstash-* | limit 10'); + await testSubjects.click('querySubmitButton'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.click('TextBasedLangEditor-expand'); + // save the visualization + await testSubjects.click('unifiedHistogramSaveVisualization'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.lens.saveModal('TextBasedChart1', false, false, false, 'new'); + await testSubjects.existOrFail('embeddablePanelHeading-TextBasedChart1'); + await elasticChart.setNewChartUiDebugFlag(true); + await PageObjects.header.waitUntilLoadingHasFinished(); + // open the inline editing flyout + await testSubjects.click('embeddablePanelToggleMenuIcon'); + await testSubjects.click('embeddablePanelAction-ACTION_CONFIGURE_IN_LENS'); + await PageObjects.header.waitUntilLoadingHasFinished(); + + // change the query + await monacoEditor.setCodeEditorValue('from logstash-* | stats maxB = max(bytes)'); + await testSubjects.click('TextBasedLangEditor-run-query-button'); + await PageObjects.header.waitUntilLoadingHasFinished(); + + expect((await PageObjects.lens.getMetricVisualizationData()).length).to.be.equal(1); + + // change the query to display a datatabler + await monacoEditor.setCodeEditorValue('from logstash-* | limit 10'); + await testSubjects.click('TextBasedLangEditor-run-query-button'); + await PageObjects.lens.waitForVisualization(); + expect(await testSubjects.exists('lnsDataTable')).to.be(true); + + await PageObjects.lens.removeDimension('lnsDatatable_metrics'); + await PageObjects.lens.removeDimension('lnsDatatable_metrics'); + await PageObjects.lens.removeDimension('lnsDatatable_metrics'); + await PageObjects.lens.removeDimension('lnsDatatable_metrics'); + + await PageObjects.lens.configureTextBasedLanguagesDimension({ + dimension: 'lnsDatatable_metrics > lns-empty-dimension', + field: 'bytes', + keepOpen: true, + }); + await testSubjects.click('lns-indexPattern-dimensionContainerBack'); + // click donut from suggestions + await testSubjects.click('lensSuggestionsPanelToggleButton'); + await testSubjects.click('lnsSuggestion-donut'); + expect(await testSubjects.exists('partitionVisChart')).to.be(true); + }); + + it('should default title when saving chart in Discover (even when modal is closed and reopened)', async () => { + await PageObjects.discover.selectTextBaseLang(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await monacoEditor.setCodeEditorValue( + 'from logstash-* | stats averageB = avg(bytes) by extension' + ); + await testSubjects.click('querySubmitButton'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.discover.chooseLensChart('Bar vertical stacked'); + await testSubjects.click('TextBasedLangEditor-expand'); + await testSubjects.click('unifiedHistogramSaveVisualization'); + await PageObjects.header.waitUntilLoadingHasFinished(); + let title = await testSubjects.getAttribute('savedObjectTitle', 'value'); + expect(title).to.equal('Bar vertical stacked'); + await testSubjects.click('saveCancelButton'); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.click('unifiedHistogramSaveVisualization'); + await PageObjects.header.waitUntilLoadingHasFinished(); + title = await testSubjects.getAttribute('savedObjectTitle', 'value'); + expect(title).to.equal('Bar vertical stacked'); + }); }); } diff --git a/x-pack/test/functional/apps/infra/logs/ml_job_id_formats/tests.ts b/x-pack/test/functional/apps/infra/logs/ml_job_id_formats/tests.ts index ec16fe567f4e..06ea712c7ccc 100644 --- a/x-pack/test/functional/apps/infra/logs/ml_job_id_formats/tests.ts +++ b/x-pack/test/functional/apps/infra/logs/ml_job_id_formats/tests.ts @@ -30,9 +30,8 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { const requestTracker = createRequestTracker(browser, pageObjects.common); let mlJobHelper: MlJobHelper; - describe('ML job ID formats', function () { - this.tags('includeFirefox'); - + // Disabled until https://github.com/elastic/kibana/issues/171913 is addressed + describe.skip('ML job ID formats', function () { this.beforeAll(async () => { // Access to ml.api has to happen inside a test or test hook mlJobHelper = createMlJobHelper(ml.api); @@ -205,8 +204,7 @@ export default ({ getService, getPageObjects }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/171493 - describe.skip('creation and recreation', () => { + describe('creation and recreation', () => { it('create first ML job', async () => { await logsUi.logEntryRatePage.navigateTo(); await requestTracker.install(); diff --git a/x-pack/test/functional/apps/maps/group4/mvt_geotile_grid.js b/x-pack/test/functional/apps/maps/group4/mvt_geotile_grid.js index 081a1a41a93d..55e504e207d4 100644 --- a/x-pack/test/functional/apps/maps/group4/mvt_geotile_grid.js +++ b/x-pack/test/functional/apps/maps/group4/mvt_geotile_grid.js @@ -53,7 +53,7 @@ export default function ({ getPageObjects, getService }) { index: 'logstash-*', gridPrecision: '8', renderAs: 'grid', - requestBody: `(aggs:(max_of_bytes:(max:(field:bytes))),fields:!((field:'@timestamp',format:date_time),(field:'relatedContent.article:modified_time',format:date_time),(field:'relatedContent.article:published_time',format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((range:('@timestamp':(format:strict_date_optional_time,gte:'2015-09-20T00:00:00.000Z',lte:'2015-09-20T01:00:00.000Z')))),must:!(),must_not:!(),should:!())),runtime_mappings:())`, + requestBody: `(aggs:(max_of_bytes:(max:(field:bytes))),fields:!((field:'@timestamp',format:date_time),(field:'relatedContent.article:modified_time',format:date_time),(field:'relatedContent.article:published_time',format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((range:('@timestamp':(format:strict_date_optional_time,gte:'2015-09-20T00:00:00.000Z',lte:'2015-09-20T01:00:00.000Z'))),(exists:(field:geo.coordinates))),must:!(),must_not:!(),should:!())),runtime_mappings:())`, }); //Should correctly load meta for style-rule (sigma is set to 1, opacity to 1) diff --git a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js index cd779392ba82..e624ab39dee1 100644 --- a/x-pack/test/functional/apps/maps/group4/mvt_scaling.js +++ b/x-pack/test/functional/apps/maps/group4/mvt_scaling.js @@ -55,7 +55,7 @@ export default function ({ getPageObjects, getService }) { hasLabels: 'false', index: 'geo_shapes*', requestBody: - '(fields:!(prop1),query:(bool:(filter:!(),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10001)', + '(fields:!(prop1),query:(bool:(filter:!((exists:(field:geometry))),must:!(),must_not:!(),should:!())),runtime_mappings:(),size:10001)', }); }); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_charts_dashboard_embeddables.ts b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_charts_dashboard_embeddables.ts index 9927f37a6c8f..19b48858b115 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_charts_dashboard_embeddables.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_charts_dashboard_embeddables.ts @@ -40,7 +40,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); await PageObjects.common.setTime({ from, to }); @@ -48,7 +48,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); await PageObjects.common.unsetTime(); }); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_embeddables_migration.ts b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_embeddables_migration.ts index 2760c3c13655..8e942d8e1e4b 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_embeddables_migration.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/anomaly_embeddables_migration.ts @@ -70,7 +70,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -85,7 +85,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/map_to_ml.ts b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/map_to_ml.ts index 3ce45876f77b..f77c46de6341 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_integrations/map_to_ml.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_integrations/map_to_ml.ts @@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.securityUI.loginAsMlPowerUser(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await kibanaServer.importExport.load(dashboardArchive); await browser.setWindowSize(1920, 1080); }); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts index 2c9c9cb7a6b9..db5be20f2e97 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/advanced_job.ts @@ -199,8 +199,8 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/categorization_small'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); - await ml.testResources.createIndexPatternIfNeeded('ft_categorization_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_categorization_small', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -209,8 +209,8 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); - await ml.testResources.deleteIndexPatternByTitle('ft_categorization_small'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_categorization_small'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts index b1939d75d05c..cbdc873286f0 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/categorization_job.ts @@ -86,7 +86,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/categorization_small'); - await ml.testResources.createIndexPatternIfNeeded('ft_categorization_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_categorization_small', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -95,7 +95,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_categorization_small'); + await ml.testResources.deleteDataViewByTitle('ft_categorization_small'); }); it('job creation loads the categorization wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts index 49383315df1f..4ca0079a0e43 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_jobs_to_advanced_job.ts @@ -209,8 +209,8 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/categorization_small'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); - await ml.testResources.createIndexPatternIfNeeded('ft_categorization_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_categorization_small', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -220,8 +220,8 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); - await ml.testResources.deleteIndexPatternByTitle('ft_categorization_small'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_categorization_small'); }); describe('from multi-metric job creation wizard', function () { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts index c46944003003..ba90e58524bc 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/convert_single_metric_job_to_multi_metric.ts @@ -16,16 +16,16 @@ export default function ({ getService }: FtrProviderContext) { const calendarId = `wizard-test-calendar_${Date.now()}`; const remoteName = 'ftr-remote:'; - const indexPatternName = 'ft_farequote'; - const indexPatternString = config.get('esTestCluster.ccs') - ? remoteName + indexPatternName - : indexPatternName; + const esIndexPatternName = 'ft_farequote'; + const esIndexPatternString = config.get('esTestCluster.ccs') + ? remoteName + esIndexPatternName + : esIndexPatternName; describe('single metric job conversion to multi-metric job', function () { this.tags(['ml']); before(async () => { await esNode.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternString, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(esIndexPatternString, '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -34,7 +34,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle(indexPatternString); + await ml.testResources.deleteDataViewByTitle(esIndexPatternString); }); const jobId = `fq_single_to_multi_${Date.now()}`; @@ -59,7 +59,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.jobManagement.navigateToNewJobSourceSelection(); await ml.testExecution.logTestStep('loads the job type selection page'); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(indexPatternString); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(esIndexPatternString); await ml.testExecution.logTestStep('loads the single metric job wizard page'); await ml.jobTypeSelection.selectSingleMetricJob(); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/custom_urls.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/custom_urls.ts index dd8b72c3504a..5a557d227094 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/custom_urls.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/custom_urls.ts @@ -69,7 +69,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); testDashboardId = await ml.testResources.createMLTestDashboardIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -80,7 +80,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.testResources.deleteMLTestDashboard(); await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('opens the custom URLs tab in the edit job flyout', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts index d63f6af6c048..864d89b2b08f 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/date_nanos_job.ts @@ -94,17 +94,14 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/event_rate_nanos'); - await ml.testResources.createIndexPatternIfNeeded( - 'ft_event_rate_gen_trend_nanos', - '@timestamp' - ); + await ml.testResources.createDataViewIfNeeded('ft_event_rate_gen_trend_nanos', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_event_rate_gen_trend_nanos'); + await ml.testResources.deleteDataViewByTitle('ft_event_rate_gen_trend_nanos'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/delete_job_and_delete_annotations.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/delete_job_and_delete_annotations.ts index 13ab18934f94..ebfc468ff86d 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/delete_job_and_delete_annotations.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/delete_job_and_delete_annotations.ts @@ -20,10 +20,10 @@ export default function ({ getService }: FtrProviderContext) { const ml = getService('ml'); const remoteName = 'ftr-remote:'; - const indexPatternName = 'ft_farequote'; - const indexPatternString = config.get('esTestCluster.ccs') - ? remoteName + indexPatternName - : indexPatternName; + const esIndexPatternName = 'ft_farequote'; + const esIndexPatternString = config.get('esTestCluster.ccs') + ? remoteName + esIndexPatternName + : esIndexPatternName; const testSetupJobConfigs = [SINGLE_METRIC_JOB_CONFIG, MULTI_METRIC_JOB_CONFIG]; @@ -64,7 +64,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esNode.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternString, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(esIndexPatternString, '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -72,7 +72,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle(indexPatternString); + await ml.testResources.deleteDataViewByTitle(esIndexPatternString); }); for (const { suiteTitle, jobId, deleteAnnotations, expectedAnnotations } of testConfigs) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts index daed44cce85f..35d6d40cdbe2 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/geo_job.ts @@ -84,7 +84,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -93,7 +93,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it('job creation loads the geo wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts index 9bbfdef22ce5..fa2e5d11eca0 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/multi_metric_job.ts @@ -84,7 +84,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -93,7 +93,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('job creation loads the multi metric wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts index ea02186c45b7..5451ea16d8e4 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/population_job.ts @@ -98,7 +98,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -107,7 +107,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it('job creation loads the population wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts index 7d9c528d763d..b8493e2daa1b 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/saved_search_job.ts @@ -269,7 +269,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.createSavedSearchFarequoteFilterIfNeeded(); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded(); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); @@ -283,7 +283,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts index b1575f0fa57b..7ce5d1838a1a 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job.ts @@ -75,10 +75,10 @@ export default function ({ getService }: FtrProviderContext) { const calendarId = `wizard-test-calendar_${Date.now()}`; const remoteName = 'ftr-remote:'; - const indexPatternName = 'ft_farequote'; - const indexPatternString = config.get('esTestCluster.ccs') - ? remoteName + indexPatternName - : indexPatternName; + const esIndexPatternName = 'ft_farequote'; + const esIndexPatternString = config.get('esTestCluster.ccs') + ? remoteName + esIndexPatternName + : esIndexPatternName; const fieldStatsEntries = [ { @@ -92,7 +92,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esNode.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternString, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(esIndexPatternString, '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createCalendar(calendarId); @@ -101,7 +101,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle(indexPatternString); + await ml.testResources.deleteDataViewByTitle(esIndexPatternString); }); it('job creation loads the single metric wizard for the source data', async () => { @@ -113,7 +113,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.jobManagement.navigateToNewJobSourceSelection(); await ml.testExecution.logTestStep('job creation loads the job type selection page'); - await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(indexPatternString); + await ml.jobSourceSelection.selectSourceForAnomalyDetectionJob(esIndexPatternString); await ml.testExecution.logTestStep('job creation loads the single metric job wizard page'); await ml.jobTypeSelection.selectSingleMetricJob(); @@ -230,7 +230,7 @@ export default function ({ getService }: FtrProviderContext) { it('job cloning creates a temporary data view and opens the single metric wizard if a matching data view does not exist', async () => { await ml.testExecution.logTestStep('delete data view used by job'); - await ml.testResources.deleteIndexPatternByTitle(indexPatternString); + await ml.testResources.deleteDataViewByTitle(esIndexPatternString); // Refresh page to ensure page has correct cache of data views await browser.refresh(); @@ -244,7 +244,7 @@ export default function ({ getService }: FtrProviderContext) { it('job cloning opens the existing job in the single metric wizard', async () => { await ml.testExecution.logTestStep('recreate data view used by job'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternString, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(esIndexPatternString, '@timestamp'); await ml.navigation.navigateToMl(); await ml.navigation.navigateToJobManagement(); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts index 4cdea1a726fe..7d1724fbd018 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_jobs/single_metric_job_without_datafeed_start.ts @@ -60,7 +60,7 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['ml']); before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -68,7 +68,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('job creation loads the single metric wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/aggregated_scripted_job.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/aggregated_scripted_job.ts index 66261321ccb8..4d9fd0bbead8 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/aggregated_scripted_job.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/aggregated_scripted_job.ts @@ -364,16 +364,16 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); }); after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); }); for (const testData of supportedTestSuites) { describe(testData.suiteTitle, function () { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts index 05e38d565e96..ab1177d2dbc8 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/annotations.ts @@ -32,7 +32,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); const JOB_CONFIG = ml.commonConfig.getADFqSingleMetricJobConfig(jobId); @@ -47,7 +47,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); describe('creating', function () { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts index 29cc28993d6c..a6e867676d10 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts @@ -76,7 +76,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.createMLTestDashboardIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -85,7 +85,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await ml.testResources.deleteMLTestDashboard(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts index 93ec331230a8..3a60e8fca97c 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts @@ -45,7 +45,7 @@ export default function ({ getService }: FtrProviderContext) { describe('with single metric job', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob(JOB_CONFIG, DATAFEED_CONFIG); @@ -54,7 +54,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('opens a job from job list link', async () => { diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts index 809ebf204e2a..1779589a5a0c 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts @@ -46,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { describe('with single metric job', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob(JOB_CONFIG, DATAFEED_CONFIG); @@ -55,7 +55,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('opens a job from job list link', async () => { @@ -134,7 +134,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob(jobConfig, datafeedConfig); await ml.securityUI.loginAsMlPowerUser(); @@ -142,7 +142,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it('opens a job from job list link', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts index 6dd953a84e4d..9bf4bc7c41c1 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts @@ -17,7 +17,7 @@ import { const testDiscoverCustomUrl: DiscoverUrlConfig = { label: 'Show data', - indexPattern: 'ft_bank_marketing', + indexName: 'ft_bank_marketing', queryEntityFieldNames: ['day'], timeRange: TIME_RANGE_TYPE.AUTO, }; @@ -43,7 +43,7 @@ export default function ({ getService }: FtrProviderContext) { let testDashboardId: string | null = null; before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/bm_classification'); - await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing'); + await ml.testResources.createDataViewIfNeeded('ft_bank_marketing'); await ml.testResources.setKibanaTimeZoneToUTC(); testDashboardId = await ml.testResources.createMLTestDashboardIfNeeded(); @@ -52,7 +52,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_bank_marketing'); + await ml.testResources.deleteDataViewByTitle('ft_bank_marketing'); }); const jobId = `bm_1_${Date.now()}`; @@ -76,7 +76,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'y', trainingPercent: 20, modelMemory: '60mb', - createIndexPattern: true, + createDataView: true, fieldStatsEntries: [ { fieldName: 'age', @@ -201,7 +201,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -338,10 +338,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts index 1444c13192e5..6efa43ac14cc 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts @@ -18,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) { describe.skip('classification saved search creation', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote_small'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote_small', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded('ft_farequote_small'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded('ft_farequote_small'); // Need to use the saved searches with filters that match multiple airlines @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote_small'); + await ml.testResources.deleteDataViewByTitle('ft_farequote_small'); }); const dateNow = Date.now(); @@ -93,7 +93,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'airline', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { fieldStatsValues: { airline: ['AAL', 'AWE', 'ASA', 'ACA', 'AMX'] } as Record< string, @@ -193,7 +193,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'airline', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { fieldStatsValues: { airline: ['AAL', 'AWE', 'ASA', 'ACA', 'AMX'] } as Record< string, @@ -293,7 +293,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'airline', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { fieldStatsValues: { airline: ['AAL', 'ASA'], @@ -385,7 +385,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'airline', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { fieldStatsValues: { airline: ['ASA', 'FFT'] } as Record, source: 'ft_farequote_small', @@ -463,7 +463,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -592,10 +592,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/cloning.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/cloning.ts index 19baea2c48c1..da62f44fb305 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/cloning.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/cloning.ts @@ -19,7 +19,7 @@ export default function ({ getService }: FtrProviderContext) { const testDataList: Array<{ suiteTitle: string; archive: string; - indexPattern: { name: string; timeField: string }; + dataView: { name: string; timeField: string }; job: DeepPartial; }> = (() => { const timestamp = Date.now(); @@ -28,7 +28,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'classification job supported by the form', archive: 'x-pack/test/functional/es_archives/ml/bm_classification', - indexPattern: { name: 'ft_bank_marketing', timeField: '@timestamp' }, + dataView: { name: 'ft_bank_marketing', timeField: '@timestamp' }, job: { id: `bm_1_${timestamp}`, description: @@ -63,7 +63,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'outlier detection job supported by the form', archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier', - indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, + dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, job: { id: `ihp_1_${timestamp}`, description: 'This is the job description', @@ -92,7 +92,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'regression job supported by the form', archive: 'x-pack/test/functional/es_archives/ml/egs_regression', - indexPattern: { name: 'ft_egs_regression', timeField: '@timestamp' }, + dataView: { name: 'ft_egs_regression', timeField: '@timestamp' }, job: { id: `egs_1_${timestamp}`, description: 'This is the job description', @@ -141,9 +141,9 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded(testData.archive); - await ml.testResources.createIndexPatternIfNeeded( - testData.indexPattern.name, - testData.indexPattern.timeField + await ml.testResources.createDataViewIfNeeded( + testData.dataView.name, + testData.dataView.timeField ); await ml.api.createDataFrameAnalyticsJob(testData.job as DataFrameAnalyticsConfig); @@ -157,9 +157,9 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.deleteIndices(cloneDestIndex); await ml.api.deleteIndices(testData.job.dest!.index as string); - await ml.testResources.deleteIndexPatternByTitle(testData.job.dest!.index as string); - await ml.testResources.deleteIndexPatternByTitle(cloneDestIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.indexPattern.name); + await ml.testResources.deleteDataViewByTitle(testData.job.dest!.index as string); + await ml.testResources.deleteDataViewByTitle(cloneDestIndex); + await ml.testResources.deleteDataViewByTitle(testData.dataView.name); }); it('opens the existing job in the data frame analytics job wizard', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/custom_urls.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/custom_urls.ts index a5dad1827d27..dac2d1ae1fa3 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/custom_urls.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/custom_urls.ts @@ -15,7 +15,7 @@ import { const testDiscoverCustomUrl: DiscoverUrlConfig = { label: 'Show data', - indexPattern: 'ft_farequote', + indexName: 'ft_farequote', queryEntityFieldNames: ['airline'], timeRange: TIME_RANGE_TYPE.AUTO, }; @@ -70,7 +70,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); await ml.api.createAndRunDFAJob(dfaJobConfig); @@ -79,7 +79,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); await ml.api.deleteIndices('user-farequote_small'); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); describe('run custom urls', function () { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts index 8b4514add92c..85624edc27a5 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts @@ -17,7 +17,7 @@ import { const testDiscoverCustomUrl: DiscoverUrlConfig = { label: 'Show data', - indexPattern: 'ft_ihp_outlier', + indexName: 'ft_ihp_outlier', queryEntityFieldNames: ['SaleType'], timeRange: TIME_RANGE_TYPE.AUTO, }; @@ -44,7 +44,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier'); testDashboardId = await ml.testResources.createMLTestDashboardIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -53,7 +53,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'); + await ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'); }); const jobId = `ihp_1_${Date.now()}`; @@ -83,7 +83,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, modelMemory: '5mb', - createIndexPattern: true, + createDataView: true, advancedEditorContent: [ '{', ' "description": "Outlier detection job based on ft_ihp_outlier dataset with runtime fields",', @@ -192,7 +192,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -324,10 +324,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts index a6f68a8eafd0..eae64ccf532d 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts @@ -16,7 +16,7 @@ export default function ({ getService }: FtrProviderContext) { describe('outlier detection saved search creation', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote_small'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote_small', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded('ft_farequote_small'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded('ft_farequote_small'); await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded( @@ -31,7 +31,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote_small'); + await ml.testResources.deleteDataViewByTitle('ft_farequote_small'); }); const dateNow = Date.now(); @@ -63,7 +63,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, modelMemory: '1mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', histogramCharts: [ @@ -140,7 +140,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, modelMemory: '65mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', histogramCharts: [ @@ -217,7 +217,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, modelMemory: '65mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', histogramCharts: [ @@ -295,7 +295,7 @@ export default function ({ getService }: FtrProviderContext) { }, }, modelMemory: '65mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', histogramCharts: [ @@ -362,7 +362,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -463,10 +463,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts index b4ed75c35043..d59f31f41232 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { const testDiscoverCustomUrl: DiscoverUrlConfig = { label: 'Show data', - indexPattern: 'ft_egs_regression', + indexName: 'ft_egs_regression', queryEntityFieldNames: ['stabf'], timeRange: TIME_RANGE_TYPE.AUTO, }; @@ -57,7 +57,7 @@ export default function ({ getService }: FtrProviderContext) { let testDashboardId: string | null = null; before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/egs_regression'); - await ml.testResources.createIndexPatternIfNeeded('ft_egs_regression'); + await ml.testResources.createDataViewIfNeeded('ft_egs_regression'); await ml.testResources.setKibanaTimeZoneToUTC(); testDashboardId = await ml.testResources.createMLTestDashboardIfNeeded(); @@ -66,7 +66,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_egs_regression'); + await ml.testResources.deleteDataViewByTitle('ft_egs_regression'); }); const jobId = `egs_1_${Date.now()}`; @@ -90,7 +90,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'stab', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, advancedEditorContent: [ '{', ' "description": "Regression job based on ft_egs_regression dataset with runtime fields",', @@ -197,7 +197,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -339,10 +339,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts index 043f546dea69..a226ea7cdbe7 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts @@ -16,7 +16,7 @@ export default function ({ getService }: FtrProviderContext) { describe('regression saved search creation', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote_small'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote_small', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote_small', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded('ft_farequote_small'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded('ft_farequote_small'); await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded( @@ -31,7 +31,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote_small'); + await ml.testResources.deleteDataViewByTitle('ft_farequote_small'); }); const dateNow = Date.now(); @@ -73,7 +73,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'responsetime', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'], @@ -161,7 +161,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'responsetime', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'], @@ -249,7 +249,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'responsetime', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'], @@ -331,7 +331,7 @@ export default function ({ getService }: FtrProviderContext) { dependentVariable: 'responsetime', trainingPercent: 20, modelMemory: '20mb', - createIndexPattern: true, + createDataView: true, expected: { source: 'ft_farequote_small', runtimeFieldsEditorContent: ['{', ' "uppercase_airline": {', ' "type": "keyword",'], @@ -401,7 +401,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); - await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await ml.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the data frame analytics wizard', async () => { @@ -498,10 +498,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.continueToCreateStep(); await ml.testExecution.logTestStep('sets the create data view switch'); - await ml.dataFrameAnalyticsCreation.assertCreateIndexPatternSwitchExists(); - await ml.dataFrameAnalyticsCreation.setCreateIndexPatternSwitchState( - testData.createIndexPattern - ); + await ml.dataFrameAnalyticsCreation.assertCreateDataViewSwitchExists(); + await ml.dataFrameAnalyticsCreation.setCreateDataViewSwitchState(testData.createDataView); }); it('runs the analytics job and displays it correctly in the job list', async () => { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts index 77cae02f3cfc..7ccf329222a5 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/results_view_content.ts @@ -18,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) { const testDataList: Array<{ suiteTitle: string; archive: string; - indexPattern: { name: string; timeField: string }; + dataView: { name: string; timeField: string }; job: DeepPartial; sortBy: { column: string; @@ -38,7 +38,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'binary classification job', archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier', - indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, + dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, job: { id: `ihp_fi_binary_${timestamp}`, description: @@ -107,7 +107,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'multi class classification job', archive: 'x-pack/test/functional/es_archives/ml/ihp_outlier', - indexPattern: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, + dataView: { name: 'ft_ihp_outlier', timeField: '@timestamp' }, job: { id: `ihp_fi_multi_${timestamp}`, description: @@ -178,7 +178,7 @@ export default function ({ getService }: FtrProviderContext) { { suiteTitle: 'regression job', archive: 'x-pack/test/functional/es_archives/ml/egs_regression', - indexPattern: { name: 'ft_egs_regression', timeField: '@timestamp' }, + dataView: { name: 'ft_egs_regression', timeField: '@timestamp' }, job: { id: `egs_fi_reg_${timestamp}`, description: 'This is the job description', @@ -252,9 +252,9 @@ export default function ({ getService }: FtrProviderContext) { await ml.securityUI.loginAsMlPowerUser(); for (const testData of testDataList) { await esArchiver.loadIfNeeded(testData.archive); - await ml.testResources.createIndexPatternIfNeeded( - testData.indexPattern.name, - testData.indexPattern.timeField + await ml.testResources.createDataViewIfNeeded( + testData.dataView.name, + testData.dataView.timeField ); await ml.api.createAndRunDFAJob(testData.job as DataFrameAnalyticsConfig); } @@ -263,7 +263,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); for (const testData of testDataList) { - await ml.testResources.deleteIndexPatternByTitle(testData.indexPattern.name); + await ml.testResources.deleteDataViewByTitle(testData.dataView.name); } }); @@ -273,13 +273,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataFrameAnalytics(); await ml.dataFrameAnalyticsTable.waitForAnalyticsToLoad(); - await ml.testResources.createIndexPatternIfNeeded(testData.job.dest!.index as string); + await ml.testResources.createDataViewIfNeeded(testData.job.dest!.index as string); await ml.dataFrameAnalyticsTable.openResultsView(testData.job.id as string); }); after(async () => { await ml.api.deleteIndices(testData.job.dest!.index as string); - await ml.testResources.deleteIndexPatternByTitle(testData.job.dest!.index as string); + await ml.testResources.deleteDataViewByTitle(testData.job.dest!.index as string); }); it('should display the total feature importance in the results view', async () => { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/data_drift.ts b/x-pack/test/functional/apps/ml/data_visualizer/data_drift.ts index 5195997c3ba3..bec899910441 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/data_drift.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/data_drift.ts @@ -84,10 +84,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('data drift', async function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.createSavedSearchFarequoteFilterAndKueryIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -97,10 +97,10 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await esArchiver.unload('x-pack/test/functional/es_archives/ml/ihp_outlier'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await Promise.all([ - ml.testResources.deleteIndexPatternByTitle('ft_fare*'), - ml.testResources.deleteIndexPatternByTitle('ft_fare*,ft_fareq*'), - ml.testResources.deleteIndexPatternByTitle('ft_farequote'), - ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'), + ml.testResources.deleteDataViewByTitle('ft_fare*'), + ml.testResources.deleteDataViewByTitle('ft_fare*,ft_fareq*'), + ml.testResources.deleteDataViewByTitle('ft_farequote'), + ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'), ]); }); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index 073023ed6b5d..f0185fc37100 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -26,7 +26,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the index data visualizer page` @@ -147,8 +147,8 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/module_sample_logs'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_module_sample_logs', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_module_sample_logs', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded(); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); await ml.testResources.createSavedSearchFarequoteFilterAndKueryIfNeeded(); @@ -159,8 +159,8 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { after(async () => { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_logs'); }); describe('with farequote', function () { @@ -223,7 +223,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the index data visualizer page` diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts index c7e00f8ed5b5..6f259a8120d2 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts @@ -14,7 +14,7 @@ export default function ({ getService }: FtrProviderContext) { describe('index based actions panel on trial license', function () { this.tags(['ml']); - const indexPatternName = 'ft_farequote'; + const esIndexName = 'ft_farequote'; const advancedJobWizardDatafeedQuery = JSON.stringify( { @@ -33,7 +33,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternName, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(esIndexName, '@timestamp'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -42,7 +42,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle(indexPatternName); + await ml.testResources.deleteDataViewByTitle(esIndexName); }); describe('create advanced job action', function () { @@ -52,10 +52,10 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToDataVisualizer(); await ml.testExecution.logTestStep('loads the saved search selection page'); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep('loads the index data visualizer page'); - await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(indexPatternName); + await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(esIndexName); }); it('opens the advanced job wizard', async () => { @@ -84,7 +84,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToDataVisualizer(); await ml.testExecution.logTestStep('loads the saved search selection page'); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep('loads the index data visualizer page'); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(savedSearch); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_data_view_management.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_data_view_management.ts index 6f15f5a33274..28611dbcb8a1 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_data_view_management.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_data_view_management.ts @@ -118,7 +118,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the index data visualizer page` @@ -182,12 +182,12 @@ export default function ({ getService }: FtrProviderContext) { }); beforeEach(async () => { - await ml.testResources.createIndexPatternIfNeeded(indexPatternTitle, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(indexPatternTitle, '@timestamp'); await navigateToIndexDataVisualizer(originalTestData); }); afterEach(async () => { - await ml.testResources.deleteIndexPatternByTitle(indexPatternTitle); + await ml.testResources.deleteDataViewByTitle(indexPatternTitle); }); it(`adds new field`, async () => { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_filters.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_filters.ts index be8c06028685..4be111e00bc8 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_filters.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_filters.ts @@ -54,7 +54,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the index data visualizer page` @@ -91,7 +91,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the saved search selection page` ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep( `${testData.suiteTitle} loads the index data visualizer page` @@ -124,7 +124,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('data visualizer with pinned global filters', function () { before(async function () { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded(); await ml.testResources.createSavedSearchFarequoteFilterAndKueryIfNeeded(); @@ -133,7 +133,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async function () { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); describe(`with ${farequoteDataViewTestData.suiteTitle}`, function () { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts index 47c6e7725686..7d38012c3651 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_dashboard.ts @@ -115,7 +115,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('field statistics in Dashboard', function () { before(async function () { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded(); await ml.securityUI.loginAsMlPowerUser(); }); @@ -123,7 +123,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async function () { await ml.testResources.clearAdvancedSettingProperty(SHOW_FIELD_STATISTICS); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); runTests(farequoteLuceneFiltersSearchTestData); diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts index c0c7a47414ce..34a8d59cc214 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_grid_in_discover.ts @@ -96,8 +96,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { before(async function () { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/module_sample_logs'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_module_sample_logs', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_module_sample_logs', '@timestamp'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded(); await ml.testResources.createSavedSearchFarequoteFilterAndLuceneIfNeeded(); @@ -109,8 +109,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async function () { await ml.testResources.clearAdvancedSettingProperty(SHOW_FIELD_STATISTICS); await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_logs'); }); describe('when enabled', function () { diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_random_sampler.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_random_sampler.ts index ce74bbfb8884..e5fee365ff08 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_random_sampler.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_random_sampler.ts @@ -17,7 +17,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await ml.navigation.navigateToDataVisualizer(); await ml.testExecution.logTestStep(`loads the saved search selection page`); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep(`loads the index data visualizer page`); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(sourceIndexOrSavedSearch); @@ -28,8 +28,8 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/module_sample_logs'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_module_sample_logs', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_module_sample_logs', '@timestamp'); await ml.testResources.createSavedSearchFarequoteLuceneIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -40,8 +40,8 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { after(async () => { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_logs'); await browser.removeLocalStorageItem('dataVisualizer.randomSamplerPreference'); }); diff --git a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts index 1c289dd66f0e..b986d29c7fee 100644 --- a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts +++ b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts @@ -132,9 +132,9 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/module_sample_ecommerce' ); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier', '@timestamp'); + await ml.testResources.createDataViewIfNeeded(ecIndexPattern, 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob( @@ -170,9 +170,9 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.deleteCalendar(calendarId); await ml.api.deleteFilter(filterId); await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'); - await ml.testResources.deleteIndexPatternByTitle(ecIndexPattern); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'); + await ml.testResources.deleteDataViewByTitle(ecIndexPattern); }); for (const testUser of testUsers) { @@ -387,7 +387,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep( 'should load an index into the data visualizer page' ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexPattern); await ml.testExecution.logTestStep('should display the time range step'); diff --git a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts index 960c3a6a4b0b..7ffdf2286439 100644 --- a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts +++ b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts @@ -138,9 +138,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/module_sample_ecommerce' ); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier', '@timestamp'); + await ml.testResources.createDataViewIfNeeded(ecIndexPattern, 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.api.createAndRunAnomalyDetectionLookbackJob( @@ -176,9 +176,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.api.deleteCalendar(calendarId); await ml.api.deleteFilter(filterId); await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'); - await ml.testResources.deleteIndexPatternByTitle(ecIndexPattern); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'); + await ml.testResources.deleteDataViewByTitle(ecIndexPattern); }); for (const testUser of testUsers) { @@ -378,7 +378,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await ml.testExecution.logTestStep( 'should load an index into the data visualizer page' ); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexPattern); await ml.testExecution.logTestStep('should display the time range step'); diff --git a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts index 5a50a34b4ee1..ebcdfbeb4b17 100644 --- a/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts +++ b/x-pack/test/functional/apps/ml/short_tests/model_management/model_list.ts @@ -120,7 +120,7 @@ export default function ({ getService }: FtrProviderContext) { // Need to delete index before ingest pipeline, else it will give error await ml.api.deleteIngestPipeline(modelWithPipelineAndDestIndex.modelId); - await ml.testResources.deleteIndexPatternByTitle( + await ml.testResources.deleteDataViewByTitle( modelWithPipelineAndDestIndexExpectedValues.dataViewTitle ); }); diff --git a/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts b/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts index 062b2809c375..e4511615a51a 100644 --- a/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts +++ b/x-pack/test/functional/apps/ml/short_tests/notifications/notification_list.ts @@ -29,7 +29,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('Notifications list', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -54,7 +54,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await spacesService.delete(idSpace1); await ml.api.cleanMlIndices(); await ml.testResources.cleanMLSavedObjects(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('displays a generic notification indicator', async () => { diff --git a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts index 91121528d477..32fe57b44275 100644 --- a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts +++ b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_creation.ts @@ -18,7 +18,7 @@ export default function ({ getService }: FtrProviderContext) { describe('calendar creation', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await asyncForEach(jobConfigs, async (jobConfig) => { // @ts-expect-error not full interface @@ -30,7 +30,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); afterEach(async () => { diff --git a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_edit.ts b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_edit.ts index 9f68ccc8a119..f7c1497b2b56 100644 --- a/x-pack/test/functional/apps/ml/short_tests/settings/calendar_edit.ts +++ b/x-pack/test/functional/apps/ml/short_tests/settings/calendar_edit.ts @@ -24,7 +24,7 @@ export default function ({ getService }: FtrProviderContext) { describe('calendar edit', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await asyncForEach(jobConfigs, async (jobConfig) => { // @ts-expect-error not full interface @@ -43,7 +43,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); afterEach(async () => { diff --git a/x-pack/test/functional/apps/ml/stack_management_jobs/export_jobs.ts b/x-pack/test/functional/apps/ml/stack_management_jobs/export_jobs.ts index 6976b4db4eda..0ddb7da85c52 100644 --- a/x-pack/test/functional/apps/ml/stack_management_jobs/export_jobs.ts +++ b/x-pack/test/functional/apps/ml/stack_management_jobs/export_jobs.ts @@ -257,16 +257,16 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await ml.api.cleanMlIndices(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/bm_classification'); - await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_bank_marketing', '@timestamp'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier', '@timestamp'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/egs_regression'); - await ml.testResources.createIndexPatternIfNeeded('ft_egs_regression', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_egs_regression', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -289,10 +289,10 @@ export default function ({ getService }: FtrProviderContext) { 'anomaly_detection_jobs', 'data_frame_analytics_jobs', ]); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_bank_marketing'); - await ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'); - await ml.testResources.deleteIndexPatternByTitle('ft_egs_regression'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_bank_marketing'); + await ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'); + await ml.testResources.deleteDataViewByTitle('ft_egs_regression'); }); it('opens export flyout and exports anomaly detector jobs', async () => { diff --git a/x-pack/test/functional/apps/ml/stack_management_jobs/import_jobs.ts b/x-pack/test/functional/apps/ml/stack_management_jobs/import_jobs.ts index b4782e37596e..8a3fa058fe25 100644 --- a/x-pack/test/functional/apps/ml/stack_management_jobs/import_jobs.ts +++ b/x-pack/test/functional/apps/ml/stack_management_jobs/import_jobs.ts @@ -36,8 +36,8 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.cleanMlIndices(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/bm_classification'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_bank_marketing', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_bank_marketing', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -47,8 +47,8 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await ml.api.cleanMlIndices(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_bank_marketing'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_bank_marketing'); }); for (const testData of testDataListPositive) { diff --git a/x-pack/test/functional/apps/ml/stack_management_jobs/manage_spaces.ts b/x-pack/test/functional/apps/ml/stack_management_jobs/manage_spaces.ts index 55b2bdfa1206..06ec8e19b10c 100644 --- a/x-pack/test/functional/apps/ml/stack_management_jobs/manage_spaces.ts +++ b/x-pack/test/functional/apps/ml/stack_management_jobs/manage_spaces.ts @@ -111,8 +111,8 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -137,8 +137,8 @@ export default function ({ getService }: FtrProviderContext) { } await ml.api.cleanMlIndices(); await ml.testResources.cleanMLSavedObjects([spaceIds.idSpace1]); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_ihp_outlier'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_ihp_outlier'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/ml/stack_management_jobs/synchronize.ts b/x-pack/test/functional/apps/ml/stack_management_jobs/synchronize.ts index 317a71ae79a0..42a462d25981 100644 --- a/x-pack/test/functional/apps/ml/stack_management_jobs/synchronize.ts +++ b/x-pack/test/functional/apps/ml/stack_management_jobs/synchronize.ts @@ -24,7 +24,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); @@ -40,7 +40,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.api.deleteDataFrameAnalyticsJobES(dfaJobId); } await ml.testResources.cleanMLSavedObjects(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); }); it('should have nothing to sync initially', async () => { diff --git a/x-pack/test/functional/apps/transform/actions/deleting.ts b/x-pack/test/functional/apps/transform/actions/deleting.ts index 80a00e0b09df..911c656e9fd5 100644 --- a/x-pack/test/functional/apps/transform/actions/deleting.ts +++ b/x-pack/test/functional/apps/transform/actions/deleting.ts @@ -65,7 +65,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); for (const testData of testDataList) { await transform.api.createAndRunTransform( @@ -80,11 +80,11 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { for (const testData of testDataList) { - await transform.testResources.deleteIndexPatternByTitle(testData.originalConfig.dest.index); + await transform.testResources.deleteDataViewByTitle(testData.originalConfig.dest.index); await transform.api.deleteIndices(testData.originalConfig.dest.index); } await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/transform/actions/reauthorizing.ts b/x-pack/test/functional/apps/transform/actions/reauthorizing.ts index 9f731f6947cb..f256e902eac9 100644 --- a/x-pack/test/functional/apps/transform/actions/reauthorizing.ts +++ b/x-pack/test/functional/apps/transform/actions/reauthorizing.ts @@ -138,7 +138,7 @@ export default function ({ getService }: FtrProviderContext) { ); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); for (const testData of testDataList) { await transform.api.createTransform(testData.originalConfig.id, testData.originalConfig, { @@ -157,12 +157,12 @@ export default function ({ getService }: FtrProviderContext) { await transform.securityCommon.clearAllTransformApiKeys(); for (const testData of testDataList) { - await transform.testResources.deleteIndexPatternByTitle(testData.originalConfig.dest.index); + await transform.testResources.deleteDataViewByTitle(testData.originalConfig.dest.index); await transform.api.deleteIndices(testData.originalConfig.dest.index); } await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/transform/actions/resetting.ts b/x-pack/test/functional/apps/transform/actions/resetting.ts index c6e5180dfa8f..b62772f63454 100644 --- a/x-pack/test/functional/apps/transform/actions/resetting.ts +++ b/x-pack/test/functional/apps/transform/actions/resetting.ts @@ -67,7 +67,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); for (const testData of testDataList) { await transform.api.createAndRunTransform( @@ -82,11 +82,11 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { for (const testData of testDataList) { - await transform.testResources.deleteIndexPatternByTitle(testData.originalConfig.dest.index); + await transform.testResources.deleteDataViewByTitle(testData.originalConfig.dest.index); await transform.api.deleteIndices(testData.originalConfig.dest.index); } await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/transform/actions/starting.ts b/x-pack/test/functional/apps/transform/actions/starting.ts index 2cccd4525856..2ecd345ac0e1 100644 --- a/x-pack/test/functional/apps/transform/actions/starting.ts +++ b/x-pack/test/functional/apps/transform/actions/starting.ts @@ -110,7 +110,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); for (const testData of testDataList) { if ( @@ -135,12 +135,12 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { for (const testData of testDataList) { - await transform.testResources.deleteIndexPatternByTitle(testData.originalConfig.dest.index); + await transform.testResources.deleteDataViewByTitle(testData.originalConfig.dest.index); await transform.api.deleteIndices(testData.originalConfig.dest.index); } await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); for (const testData of testDataList) { diff --git a/x-pack/test/functional/apps/transform/creation/index_pattern/continuous_transform.ts b/x-pack/test/functional/apps/transform/creation/index_pattern/continuous_transform.ts index e56d06e15a62..d345aabc4fab 100644 --- a/x-pack/test/functional/apps/transform/creation/index_pattern/continuous_transform.ts +++ b/x-pack/test/functional/apps/transform/creation/index_pattern/continuous_transform.ts @@ -36,7 +36,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); const DEFAULT_NUM_FAILURE_RETRIES = '5'; @@ -326,7 +326,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); after(async () => { await transform.api.deleteIndices(testData.destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await transform.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts index 69406c583042..0f461150166f 100644 --- a/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts +++ b/x-pack/test/functional/apps/transform/creation/index_pattern/creation_index_pattern.ts @@ -25,7 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe('creation_index_pattern', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await transform.testResources.setKibanaTimeZoneToUTC(); await transform.securityUI.loginAsTransformPowerUser(); @@ -33,7 +33,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); await transform.securityUI.logout(); }); @@ -509,7 +509,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await transform.api.deleteIndices(testData.destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await transform.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts index 3f0adc578389..e6f783b88eed 100644 --- a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts +++ b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_runtime_mappings.ts @@ -37,7 +37,7 @@ export default function ({ getService }: FtrProviderContext) { describe('creation with runtime mappings', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await transform.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await transform.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await transform.testResources.setKibanaTimeZoneToUTC(); await transform.securityUI.loginAsTransformPowerUser(); @@ -45,7 +45,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_farequote'); + await transform.testResources.deleteDataViewByTitle('ft_farequote'); }); const histogramCharts: HistogramCharts = [ @@ -254,7 +254,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await transform.api.deleteIndices(testData.destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await transform.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_saved_search.ts b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_saved_search.ts index c976be55a788..b0e331635610 100644 --- a/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_saved_search.ts +++ b/x-pack/test/functional/apps/transform/creation/runtime_mappings_saved_search/creation_saved_search.ts @@ -23,7 +23,7 @@ export default function ({ getService }: FtrProviderContext) { describe('creation_saved_search', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await transform.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); + await transform.testResources.createDataViewIfNeeded('ft_farequote', '@timestamp'); await transform.testResources.createSavedSearchFarequoteFilterIfNeeded(); await transform.testResources.setKibanaTimeZoneToUTC(); @@ -33,7 +33,7 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { await transform.api.cleanTransformIndices(); await transform.testResources.deleteSavedSearches(); - await transform.testResources.deleteIndexPatternByTitle('ft_farequote'); + await transform.testResources.deleteDataViewByTitle('ft_farequote'); }); const testDataList: Array = [ @@ -121,7 +121,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await transform.api.deleteIndices(testData.destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await transform.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('loads the wizard for the source data', async () => { diff --git a/x-pack/test/functional/apps/transform/edit_clone/cloning.ts b/x-pack/test/functional/apps/transform/edit_clone/cloning.ts index caa6552024e1..1645547443c0 100644 --- a/x-pack/test/functional/apps/transform/edit_clone/cloning.ts +++ b/x-pack/test/functional/apps/transform/edit_clone/cloning.ts @@ -199,7 +199,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await transform.api.createAndRunTransform( transformConfigWithPivot.id, transformConfigWithPivot @@ -223,17 +223,17 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle(transformConfigWithPivot.dest.index); - await transform.testResources.deleteIndexPatternByTitle( + await transform.testResources.deleteDataViewByTitle(transformConfigWithPivot.dest.index); + await transform.testResources.deleteDataViewByTitle( transformConfigWithRuntimeMapping.dest.index ); - await transform.testResources.deleteIndexPatternByTitle(transformConfigWithLatest.dest.index); + await transform.testResources.deleteDataViewByTitle(transformConfigWithLatest.dest.index); await transform.api.deleteIndices(transformConfigWithPivot.dest.index); await transform.api.deleteIndices(transformConfigWithRuntimeMapping.dest.index); await transform.api.deleteIndices(transformConfigWithLatest.dest.index); await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); const testDataList: TestData[] = [ @@ -397,7 +397,7 @@ export default function ({ getService }: FtrProviderContext) { describe(`${testData.suiteTitle}`, function () { after(async () => { await transform.api.deleteIndices(testData.destinationIndex); - await transform.testResources.deleteIndexPatternByTitle(testData.destinationIndex); + await transform.testResources.deleteDataViewByTitle(testData.destinationIndex); }); it('opens the existing transform in the wizard', async () => { diff --git a/x-pack/test/functional/apps/transform/edit_clone/editing.ts b/x-pack/test/functional/apps/transform/edit_clone/editing.ts index 10cacc361779..1a8394ca9a66 100644 --- a/x-pack/test/functional/apps/transform/edit_clone/editing.ts +++ b/x-pack/test/functional/apps/transform/edit_clone/editing.ts @@ -27,7 +27,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await transform.api.createAndRunTransform( transformConfigWithPivot.id, @@ -43,12 +43,12 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle(transformConfigWithPivot.dest.index); + await transform.testResources.deleteDataViewByTitle(transformConfigWithPivot.dest.index); await transform.api.deleteIndices(transformConfigWithPivot.dest.index); - await transform.testResources.deleteIndexPatternByTitle(transformConfigWithLatest.dest.index); + await transform.testResources.deleteDataViewByTitle(transformConfigWithLatest.dest.index); await transform.api.deleteIndices(transformConfigWithLatest.dest.index); await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); const testDataList = [ diff --git a/x-pack/test/functional/apps/transform/permissions/full_transform_access.ts b/x-pack/test/functional/apps/transform/permissions/full_transform_access.ts index 2e7779767eac..0d745a512399 100644 --- a/x-pack/test/functional/apps/transform/permissions/full_transform_access.ts +++ b/x-pack/test/functional/apps/transform/permissions/full_transform_access.ts @@ -55,7 +55,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await transform.api.createAndRunTransform( transformConfigWithPivot.id, @@ -67,12 +67,10 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle( - transformConfigWithPivot.dest.index - ); + await transform.testResources.deleteDataViewByTitle(transformConfigWithPivot.dest.index); await transform.api.deleteIndices(transformConfigWithPivot.dest.index); await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it('should display elements in the Transform list page correctly', async () => { diff --git a/x-pack/test/functional/apps/transform/permissions/read_transform_access.ts b/x-pack/test/functional/apps/transform/permissions/read_transform_access.ts index 4e715d4f0746..02cfcfdfba00 100644 --- a/x-pack/test/functional/apps/transform/permissions/read_transform_access.ts +++ b/x-pack/test/functional/apps/transform/permissions/read_transform_access.ts @@ -55,7 +55,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await transform.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await transform.api.createAndRunTransform( transformConfigWithPivot.id, @@ -67,12 +67,10 @@ export default function ({ getService }: FtrProviderContext) { }); after(async () => { - await transform.testResources.deleteIndexPatternByTitle( - transformConfigWithPivot.dest.index - ); + await transform.testResources.deleteDataViewByTitle(transformConfigWithPivot.dest.index); await transform.api.deleteIndices(transformConfigWithPivot.dest.index); await transform.api.cleanTransformIndices(); - await transform.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await transform.testResources.deleteDataViewByTitle('ft_ecommerce'); }); it('should display elements in the Transform list page correctly', async () => { diff --git a/x-pack/test/functional/apps/user_profiles/config.ts b/x-pack/test/functional/apps/user_profiles/config.ts new file mode 100644 index 000000000000..d0d07ff20028 --- /dev/null +++ b/x-pack/test/functional/apps/user_profiles/config.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { FtrConfigProviderContext } from '@kbn/test'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile(require.resolve('../../config.base.js')); + + return { + ...functionalConfig.getAll(), + testFiles: [require.resolve('.')], + }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/mapping.helpers.js b/x-pack/test/functional/apps/user_profiles/index.ts similarity index 52% rename from x-pack/test/api_integration/apis/management/index_management/mapping.helpers.js rename to x-pack/test/functional/apps/user_profiles/index.ts index abb790cf2f55..5932e2729bf4 100644 --- a/x-pack/test/api_integration/apis/management/index_management/mapping.helpers.js +++ b/x-pack/test/functional/apps/user_profiles/index.ts @@ -5,12 +5,10 @@ * 2.0. */ -import { API_BASE_PATH } from './constants'; +import { FtrProviderContext } from '../../ftr_provider_context'; -export const registerHelpers = ({ supertest }) => { - const getIndexMapping = (indexName) => supertest.get(`${API_BASE_PATH}/mapping/${indexName}`); - - return { - getIndexMapping, - }; +export default ({ loadTestFile }: FtrProviderContext) => { + describe('User Profiles page', function () { + loadTestFile(require.resolve('./user_profiles')); + }); }; diff --git a/x-pack/test/functional/apps/user_profiles/user_profiles.ts b/x-pack/test/functional/apps/user_profiles/user_profiles.ts new file mode 100644 index 000000000000..a9f2f7a51950 --- /dev/null +++ b/x-pack/test/functional/apps/user_profiles/user_profiles.ts @@ -0,0 +1,160 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects }: FtrProviderContext) => { + const pageObjects = getPageObjects(['common', 'userProfiles', 'settings']); + + describe('User Profile Page', async () => { + before(async () => {}); + + describe('Details', async () => { + before(async () => { + await pageObjects.common.navigateToApp('security_account'); + }); + + it('should set the full name', async () => { + await pageObjects.userProfiles.setFullNameInputField('Test User 2'); + + await pageObjects.userProfiles.saveUserProfileChanges(); + + let toast = await pageObjects.common.closeToast(); + + expect(toast).to.be('Profile updated'); + + await pageObjects.userProfiles.setFullNameInputField('test user'); + + await pageObjects.userProfiles.saveUserProfileChanges(); + + toast = await pageObjects.common.closeToast(); + + expect(toast).to.be('Profile updated'); + }); + + it('should set the email', async () => { + await pageObjects.userProfiles.setEmailInputField('test@test.com'); + + await pageObjects.userProfiles.saveUserProfileChanges(); + + let toast = await pageObjects.common.closeToast(); + + expect(toast).to.be('Profile updated'); + + await pageObjects.userProfiles.setEmailInputField('', true); + + await pageObjects.userProfiles.saveUserProfileChanges(); + + toast = await pageObjects.common.closeToast(); + + expect(toast).to.be('Profile updated'); + }); + }); + + describe('Change Password', async () => { + before(async () => { + await pageObjects.common.navigateToApp('security_account'); + }); + + it('should set the current password and enter a new password, then submit', async () => { + const changePasswordButton = await pageObjects.userProfiles.getChangePasswordButton(); + await changePasswordButton.click(); + + await pageObjects.userProfiles.setCurrentPasswordField('changeme'); + await pageObjects.userProfiles.setNewPasswordField('changeme2'); + await pageObjects.userProfiles.setConfirmPasswordField('changeme2'); + + const submitButton = await pageObjects.userProfiles.getChangePasswordFormSubmitButton(); + await submitButton.click(); + + const initialToast = await pageObjects.common.closeToast(); + + expect(initialToast).to.be('Password successfully changed'); + + await changePasswordButton.click(); + + await pageObjects.userProfiles.setCurrentPasswordField('changeme2'); + await pageObjects.userProfiles.setNewPasswordField('changeme'); + await pageObjects.userProfiles.setConfirmPasswordField('changeme'); + + await submitButton.click(); + + const resetToast = await pageObjects.common.closeToast(); + + expect(resetToast).to.be('Password successfully changed'); + }); + }); + + describe('Theme', async () => { + it('should change theme based on the User Profile Theme control with default Adv. Settings value (light)', async () => { + await pageObjects.common.navigateToApp('security_account'); + + const themeKeyPadMenu = await pageObjects.userProfiles.getThemeKeypadMenu(); + expect(themeKeyPadMenu).not.to.be(null); + + await pageObjects.userProfiles.changeUserProfileTheme('Dark'); + const darkModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(darkModeTag).to.be('v8dark'); + + await pageObjects.userProfiles.changeUserProfileTheme('Light'); + const lightModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(lightModeTag).to.be('v8light'); + + await pageObjects.userProfiles.changeUserProfileTheme('Space default'); + const spaceDefaultModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(spaceDefaultModeTag).to.be('v8light'); + }); + + it('should change theme based on the User Profile Theme control with default Adv. Settings value set to dark', async () => { + await pageObjects.common.navigateToUrl('management', 'kibana/settings', { + basePath: '', + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + shouldUseHashForSubUrl: false, + }); + + let advancedSetting = await pageObjects.settings.getAdvancedSettingCheckbox( + 'theme:darkMode' + ); + expect(advancedSetting).to.be(null); + + await pageObjects.settings.toggleAdvancedSettingCheckbox('theme:darkMode', true); + advancedSetting = await pageObjects.settings.getAdvancedSettingCheckbox('theme:darkMode'); + expect(advancedSetting).to.be('true'); + + await pageObjects.common.navigateToApp('security_account'); + + let spaceDefaultModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(spaceDefaultModeTag).to.be('v8dark'); + + await pageObjects.userProfiles.changeUserProfileTheme('Light'); + const lightModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(lightModeTag).to.be('v8light'); + + await pageObjects.userProfiles.changeUserProfileTheme('Dark'); + const darkModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(darkModeTag).to.be('v8dark'); + + await pageObjects.userProfiles.changeUserProfileTheme('Space default'); + spaceDefaultModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(spaceDefaultModeTag).to.be('v8dark'); + + await pageObjects.common.navigateToUrl('management', 'kibana/settings', { + basePath: '', + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + shouldUseHashForSubUrl: false, + }); + + await pageObjects.settings.toggleAdvancedSettingCheckbox('theme:darkMode', false); + advancedSetting = await pageObjects.settings.getAdvancedSettingCheckbox('theme:darkMode'); + expect(advancedSetting).to.be(null); + }); + }); + }); +}; diff --git a/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/data.json b/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/data.json new file mode 100644 index 000000000000..a56ba3832c67 --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/data.json @@ -0,0 +1,1268 @@ +{ + "type": "doc", + "value": { + "id": "eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1", + "index": ".alerts-security.alerts-default", + "source": { + "@timestamp": "2023-04-27T11:03:57.906Z", + "Endpoint": { + "capabilities": [ + "isolation", + "kill_process", + "suspend_process", + "running_processes", + "get_file", + "execute" + ], + "configuration": { + "isolation": true + }, + "policy": { + "applied": { + "endpoint_policy_version": 3, + "id": "C2A9093E-E289-4C0A-AA44-8C32A414FA7A", + "name": "With Eventing", + "status": "success", + "version": 5 + } + }, + "state": { + "isolation": true + }, + "status": "enrolled" + }, + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb", + "type": "endpoint", + "version": "8.8.0" + }, + "data_stream": { + "dataset": "endpoint.alerts", + "namespace": "default", + "type": "logs" + }, + "dll": [ + { + "Ext": { + "compile_time": 1534424710, + "malware_classification": { + "identifier": "Whitelisted", + "score": 0, + "threshold": 0, + "version": "3.0.0" + }, + "mapped_address": 5362483200, + "mapped_size": 0 + }, + "code_signature": { + "subject_name": "Cybereason Inc", + "trusted": true + }, + "hash": { + "md5": "1f2d082566b0fc5f2c238a5180db7451", + "sha1": "ca85243c0af6a6471bdaa560685c51eefd6dbc0d", + "sha256": "8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2" + }, + "path": "C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe", + "pe": { + "architecture": "x64" + } + } + ], + "ecs": { + "version": "1.4.0" + }, + "elastic": { + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb" + } + }, + "event.action": "creation", + "event.agent_id_status": "auth_metadata_missing", + "event.category": "malware", + "event.code": "malicious_file", + "event.dataset": "endpoint", + "event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "event.ingested": "2023-04-27T10:58:03Z", + "event.kind": "signal", + "event.module": "endpoint", + "event.sequence": 5826, + "event.type": "creation", + "file": { + "Ext": { + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "malware_classification": { + "identifier": "endpointpe", + "score": 1, + "threshold": 0.66, + "version": "3.0.33" + }, + "quarantine_message": "fake quarantine message", + "quarantine_result": true, + "temp_file_path": "C:/temp/fake_malware.exe" + }, + "accessed": 1682752652103, + "created": 1682752652103, + "hash": { + "md5": "fake file md5", + "sha1": "fake file sha1", + "sha256": "fake file sha256" + }, + "mtime": 1682752652103, + "name": "fake_malware.exe", + "owner": "SYSTEM", + "path": "C:/fake_malware.exe", + "size": 3456 + }, + "user": { + "name": "user1" + }, + "host": { + "architecture": "wtnozeqvub", + "hostname": "Host-fwarau82er", + "id": "4260adf9-5e63-445d-92c6-e03359bcd342", + "ip": [ + "10.249.37.72", + "10.150.39.243", + "10.186.17.170" + ], + "mac": [ + "f5-f-97-dc-20-67", + "b5-56-ca-98-81-ca", + "22-86-39-4c-87-33" + ], + "name": "Host-fwarau82er", + "os": { + "Ext": { + "variant": "Darwin" + }, + "family": "Darwin", + "full": "macOS Monterey", + "name": "macOS", + "platform": "macOS", + "version": "12.6.1" + } + }, + "kibana.alert.ancestors": [ + { + "depth": 0, + "id": "vT9cwocBh3b8EMpD8lsi", + "index": ".ds-logs-endpoint.alerts-default-2023.04.27-000001", + "type": "event" + } + ], + "kibana.alert.depth": 1, + "kibana.alert.last_detected": "2023-04-27T11:03:57.993Z", + "kibana.alert.original_event.action": "creation", + "kibana.alert.original_event.agent_id_status": "auth_metadata_missing", + "kibana.alert.original_event.category": "malware", + "kibana.alert.original_event.code": "malicious_file", + "kibana.alert.original_event.dataset": "endpoint", + "kibana.alert.original_event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "kibana.alert.original_event.ingested": "2023-04-27T10:58:03Z", + "kibana.alert.original_event.kind": "alert", + "kibana.alert.original_event.module": "endpoint", + "kibana.alert.original_event.sequence": 5826, + "kibana.alert.original_event.type": "creation", + "kibana.alert.original_time": "2023-04-29T07:17:32.103Z", + "kibana.alert.reason": "malware event with process malware writer, file fake_malware.exe, on Host-fwarau82er created medium alert Endpoint Security.", + "kibana.alert.risk_score": 47, + "kibana.alert.rule.actions": [ + ], + "kibana.alert.rule.author": [ + "Elastic" + ], + "kibana.alert.rule.category": "Custom Query Rule", + "kibana.alert.rule.consumer": "siem", + "kibana.alert.rule.created_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.created_by": "elastic", + "kibana.alert.rule.description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "kibana.alert.rule.enabled": true, + "kibana.alert.rule.exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "kibana.alert.rule.execution.uuid": "ebf843ff-e0e1-47f8-9ed2-cc8066afbcef", + "kibana.alert.rule.false_positives": [ + ], + "kibana.alert.rule.from": "now-10m", + "kibana.alert.rule.immutable": true, + "kibana.alert.rule.indices": [ + "logs-endpoint.alerts-*" + ], + "kibana.alert.rule.interval": "5m", + "kibana.alert.rule.license": "Elastic License v2", + "kibana.alert.rule.max_signals": 10000, + "kibana.alert.rule.name": "Endpoint Security", + "kibana.alert.rule.parameters": { + "author": [ + "Elastic" + ], + "description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "false_positives": [ + ], + "from": "now-10m", + "immutable": true, + "index": [ + "logs-endpoint.alerts-*" + ], + "language": "kuery", + "license": "Elastic License v2", + "max_signals": 10000, + "query": "event.kind:alert and event.module:(endpoint and not endgame)\n", + "references": [ + ], + "related_integrations": [ + { + "package": "endpoint", + "version": "^8.2.0" + } + ], + "required_fields": [ + { + "ecs": true, + "name": "event.kind", + "type": "keyword" + }, + { + "ecs": true, + "name": "event.module", + "type": "keyword" + } + ], + "risk_score": 47, + "risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "rule_name_override": "message", + "setup": "", + "severity": "medium", + "severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "threat": [ + ], + "timestamp_override": "event.ingested", + "to": "now", + "type": "query", + "version": 101 + }, + "kibana.alert.rule.producer": "siem", + "kibana.alert.rule.references": [ + ], + "kibana.alert.rule.revision": 0, + "kibana.alert.rule.risk_score": 47, + "kibana.alert.rule.risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "kibana.alert.rule.rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "kibana.alert.rule.rule_name_override": "message", + "kibana.alert.rule.rule_type_id": "siem.queryRule", + "kibana.alert.rule.severity": "medium", + "kibana.alert.rule.severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "kibana.alert.rule.tags": [ + "Elastic", + "Endpoint Security" + ], + "kibana.alert.rule.threat": [ + ], + "kibana.alert.rule.timestamp_override": "event.ingested", + "kibana.alert.rule.to": "now", + "kibana.alert.rule.type": "query", + "kibana.alert.rule.updated_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.updated_by": "elastic", + "kibana.alert.rule.uuid": "7015a3e2-e4ea-11ed-8c11-49608884878f", + "kibana.alert.rule.version": 101, + "kibana.alert.severity": "medium", + "kibana.alert.start": "2023-04-27T11:03:57.993Z", + "kibana.alert.status": "active", + "kibana.alert.url": "http://localhost:5601/app/security/alerts/redirect/eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1?index=.alerts-security.alerts-default×tamp=2023-04-27T11:03:57.906Z", + "kibana.alert.uuid": "eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1", + "kibana.alert.workflow_status": "open", + "kibana.space_ids": [ + "default" + ], + "kibana.version": "8.8.0", + "process": { + "Ext": { + "ancestry": [ + "qa5jgw1wr7", + "5k1hclygc6" + ], + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "token": { + "domain": "NT AUTHORITY", + "integrity_level": 16384, + "integrity_level_name": "system", + "privileges": [ + { + "description": "Replace a process level token", + "enabled": false, + "name": "SeAssignPrimaryTokenPrivilege" + } + ], + "sid": "S-1-5-18", + "type": "tokenPrimary", + "user": "SYSTEM" + }, + "user": "SYSTEM" + }, + "entity_id": "nqh8ts6ves", + "entry_leader": { + "entity_id": "jnm38bel0w", + "name": "fake entry", + "pid": 791 + }, + "executable": "C:/malware.exe", + "group_leader": { + "entity_id": "jnm38bel0w", + "name": "fake leader", + "pid": 848 + }, + "hash": { + "md5": "fake md5", + "sha1": "fake sha1", + "sha256": "fake sha256" + }, + "name": "malware writer", + "parent": { + "entity_id": "qa5jgw1wr7", + "pid": 1 + }, + "pid": 2, + "session_leader": { + "entity_id": "jnm38bel0w", + "name": "fake session", + "pid": 909 + }, + "start": 1682752652103, + "uptime": 0 + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "170865e675eda76202f0095b23869d8d0726df4c91a343876df38b566bf1e57d", + "index": ".alerts-security.alerts-default", + "source": { + "@timestamp": "2023-04-27T11:03:57.906Z", + "Endpoint": { + "capabilities": [ + "isolation", + "kill_process", + "suspend_process", + "running_processes", + "get_file", + "execute" + ], + "configuration": { + "isolation": true + }, + "policy": { + "applied": { + "endpoint_policy_version": 3, + "id": "C2A9093E-E289-4C0A-AA44-8C32A414FA7A", + "name": "With Eventing", + "status": "success", + "version": 5 + } + }, + "state": { + "isolation": true + }, + "status": "enrolled" + }, + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb", + "type": "endpoint", + "version": "8.8.0" + }, + "data_stream": { + "dataset": "endpoint.alerts", + "namespace": "default", + "type": "logs" + }, + "dll": [ + { + "Ext": { + "compile_time": 1534424710, + "malware_classification": { + "identifier": "Whitelisted", + "score": 0, + "threshold": 0, + "version": "3.0.0" + }, + "mapped_address": 5362483200, + "mapped_size": 0 + }, + "code_signature": { + "subject_name": "Cybereason Inc", + "trusted": true + }, + "hash": { + "md5": "1f2d082566b0fc5f2c238a5180db7451", + "sha1": "ca85243c0af6a6471bdaa560685c51eefd6dbc0d", + "sha256": "8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2" + }, + "path": "C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe", + "pe": { + "architecture": "x64" + } + } + ], + "ecs": { + "version": "1.4.0" + }, + "elastic": { + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb" + } + }, + "event.action": "creation", + "event.agent_id_status": "auth_metadata_missing", + "event.category": "malware", + "event.code": "malicious_file", + "event.dataset": "endpoint", + "event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "event.ingested": "2023-04-27T10:58:03Z", + "event.kind": "signal", + "event.module": "endpoint", + "event.sequence": 5826, + "event.type": "creation", + "file": { + "Ext": { + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "malware_classification": { + "identifier": "endpointpe", + "score": 1, + "threshold": 0.66, + "version": "3.0.33" + }, + "quarantine_message": "fake quarantine message", + "quarantine_result": true, + "temp_file_path": "C:/temp/fake_malware.exe" + }, + "accessed": 1682752652103, + "created": 1682752652103, + "hash": { + "md5": "fake file md5", + "sha1": "fake file sha1", + "sha256": "fake file sha256" + }, + "mtime": 1682752652103, + "name": "fake_malware.exe", + "owner": "SYSTEM", + "path": "C:/fake_malware.exe", + "size": 3456 + }, + "user": { + "name": "user1" + }, + "host": { + "architecture": "wtnozeqvub", + "hostname": "Host-fwarau82er", + "id": "4260adf9-5e63-445d-92c6-e03359bcd342", + "ip": [ + "10.249.37.72", + "10.150.39.243", + "10.186.17.170" + ], + "mac": [ + "f5-f-97-dc-20-67", + "b5-56-ca-98-81-ca", + "22-86-39-4c-87-33" + ], + "name": "Host-fwarau82er", + "os": { + "Ext": { + "variant": "Darwin" + }, + "family": "Darwin", + "full": "macOS Monterey", + "name": "macOS", + "platform": "macOS", + "version": "12.6.1" + } + }, + "kibana.alert.ancestors": [ + { + "depth": 0, + "id": "vT9cwocBh3b8EMpD8lsi", + "index": ".ds-logs-endpoint.alerts-default-2023.04.27-000001", + "type": "event" + } + ], + "kibana.alert.depth": 1, + "kibana.alert.last_detected": "2023-04-27T11:03:57.993Z", + "kibana.alert.original_event.action": "creation", + "kibana.alert.original_event.agent_id_status": "auth_metadata_missing", + "kibana.alert.original_event.category": "malware", + "kibana.alert.original_event.code": "malicious_file", + "kibana.alert.original_event.dataset": "endpoint", + "kibana.alert.original_event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "kibana.alert.original_event.ingested": "2023-04-27T10:58:03Z", + "kibana.alert.original_event.kind": "alert", + "kibana.alert.original_event.module": "endpoint", + "kibana.alert.original_event.sequence": 5826, + "kibana.alert.original_event.type": "creation", + "kibana.alert.original_time": "2023-04-29T07:17:32.103Z", + "kibana.alert.reason": "malware event with process malware writer, file fake_malware.exe, on Host-fwarau82er created medium alert Endpoint Security.", + "kibana.alert.risk_score": 47, + "kibana.alert.rule.actions": [ + ], + "kibana.alert.rule.author": [ + "Elastic" + ], + "kibana.alert.rule.category": "Custom Query Rule", + "kibana.alert.rule.consumer": "siem", + "kibana.alert.rule.created_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.created_by": "elastic", + "kibana.alert.rule.description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "kibana.alert.rule.enabled": true, + "kibana.alert.rule.exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "kibana.alert.rule.execution.uuid": "ebf843ff-e0e1-47f8-9ed2-cc8066afbcef", + "kibana.alert.rule.false_positives": [ + ], + "kibana.alert.rule.from": "now-10m", + "kibana.alert.rule.immutable": true, + "kibana.alert.rule.indices": [ + "logs-endpoint.alerts-*" + ], + "kibana.alert.rule.interval": "5m", + "kibana.alert.rule.license": "Elastic License v2", + "kibana.alert.rule.max_signals": 10000, + "kibana.alert.rule.name": "Endpoint Security", + "kibana.alert.rule.parameters": { + "author": [ + "Elastic" + ], + "description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "false_positives": [ + ], + "from": "now-10m", + "immutable": true, + "index": [ + "logs-endpoint.alerts-*" + ], + "language": "kuery", + "license": "Elastic License v2", + "max_signals": 10000, + "query": "event.kind:alert and event.module:(endpoint and not endgame)\n", + "references": [ + ], + "related_integrations": [ + { + "package": "endpoint", + "version": "^8.2.0" + } + ], + "required_fields": [ + { + "ecs": true, + "name": "event.kind", + "type": "keyword" + }, + { + "ecs": true, + "name": "event.module", + "type": "keyword" + } + ], + "risk_score": 47, + "risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "rule_name_override": "message", + "setup": "", + "severity": "medium", + "severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "threat": [ + ], + "timestamp_override": "event.ingested", + "to": "now", + "type": "query", + "version": 101 + }, + "kibana.alert.rule.producer": "siem", + "kibana.alert.rule.references": [ + ], + "kibana.alert.rule.revision": 0, + "kibana.alert.rule.risk_score": 47, + "kibana.alert.rule.risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "kibana.alert.rule.rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "kibana.alert.rule.rule_name_override": "message", + "kibana.alert.rule.rule_type_id": "siem.queryRule", + "kibana.alert.rule.severity": "medium", + "kibana.alert.rule.severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "kibana.alert.rule.tags": [ + "Elastic", + "Endpoint Security" + ], + "kibana.alert.rule.threat": [ + ], + "kibana.alert.rule.timestamp_override": "event.ingested", + "kibana.alert.rule.to": "now", + "kibana.alert.rule.type": "query", + "kibana.alert.rule.updated_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.updated_by": "elastic", + "kibana.alert.rule.uuid": "7015a3e2-e4ea-11ed-8c11-49608884878f", + "kibana.alert.rule.version": 101, + "kibana.alert.severity": "medium", + "kibana.alert.start": "2023-04-27T11:03:57.993Z", + "kibana.alert.status": "active", + "kibana.alert.url": "http://localhost:5601/app/security/alerts/redirect/eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1?index=.alerts-security.alerts-default×tamp=2023-04-27T11:03:57.906Z", + "kibana.alert.uuid": "eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1", + "kibana.alert.workflow_status": "open", + "kibana.space_ids": [ + "default" + ], + "kibana.version": "8.8.0", + "process": { + "Ext": { + "ancestry": [ + "qa5jgw1wr7", + "5k1hclygc6" + ], + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "token": { + "domain": "NT AUTHORITY", + "integrity_level": 16384, + "integrity_level_name": "system", + "privileges": [ + { + "description": "Replace a process level token", + "enabled": false, + "name": "SeAssignPrimaryTokenPrivilege" + } + ], + "sid": "S-1-5-18", + "type": "tokenPrimary", + "user": "SYSTEM" + }, + "user": "SYSTEM" + }, + "entity_id": "nqh8ts6ves", + "entry_leader": { + "entity_id": "jnm38bel0w", + "name": "fake entry", + "pid": 791 + }, + "executable": "C:/malware.exe", + "group_leader": { + "entity_id": "jnm38bel0w", + "name": "fake leader", + "pid": 848 + }, + "hash": { + "md5": "fake md5", + "sha1": "fake sha1", + "sha256": "fake sha256" + }, + "name": "malware writer", + "parent": { + "entity_id": "qa5jgw1wr7", + "pid": 1 + }, + "pid": 2, + "session_leader": { + "entity_id": "jnm38bel0w", + "name": "fake session", + "pid": 909 + }, + "start": 1682752652103, + "uptime": 0 + } + } + } +} + +{ + "type": "doc", + "value": { + "id": "f3bbdf17847c703e37dca942dc6c1db69eb8af18a74c1f52b6d0bd76c6b3b135", + "index": ".alerts-security.alerts-default", + "source": { + "@timestamp": "2023-04-27T11:03:57.906Z", + "Endpoint": { + "capabilities": [ + "isolation", + "kill_process", + "suspend_process", + "running_processes", + "get_file", + "execute" + ], + "configuration": { + "isolation": true + }, + "policy": { + "applied": { + "endpoint_policy_version": 3, + "id": "C2A9093E-E289-4C0A-AA44-8C32A414FA7A", + "name": "With Eventing", + "status": "success", + "version": 5 + } + }, + "state": { + "isolation": true + }, + "status": "enrolled" + }, + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb", + "type": "endpoint", + "version": "8.8.0" + }, + "data_stream": { + "dataset": "endpoint.alerts", + "namespace": "default", + "type": "logs" + }, + "dll": [ + { + "Ext": { + "compile_time": 1534424710, + "malware_classification": { + "identifier": "Whitelisted", + "score": 0, + "threshold": 0, + "version": "3.0.0" + }, + "mapped_address": 5362483200, + "mapped_size": 0 + }, + "code_signature": { + "subject_name": "Cybereason Inc", + "trusted": true + }, + "hash": { + "md5": "1f2d082566b0fc5f2c238a5180db7451", + "sha1": "ca85243c0af6a6471bdaa560685c51eefd6dbc0d", + "sha256": "8ad40c90a611d36eb8f9eb24fa04f7dbca713db383ff55a03aa0f382e92061a2" + }, + "path": "C:\\Program Files\\Cybereason ActiveProbe\\AmSvc.exe", + "pe": { + "architecture": "x64" + } + } + ], + "ecs": { + "version": "1.4.0" + }, + "elastic": { + "agent": { + "id": "b563ce99-e373-4a1f-a5fe-97e956140aeb" + } + }, + "event.action": "creation", + "event.agent_id_status": "auth_metadata_missing", + "event.category": "malware", + "event.code": "malicious_file", + "event.dataset": "endpoint", + "event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "event.ingested": "2023-04-27T10:58:03Z", + "event.kind": "signal", + "event.module": "endpoint", + "event.sequence": 5826, + "event.type": "creation", + "file": { + "Ext": { + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "malware_classification": { + "identifier": "endpointpe", + "score": 1, + "threshold": 0.66, + "version": "3.0.33" + }, + "quarantine_message": "fake quarantine message", + "quarantine_result": true, + "temp_file_path": "C:/temp/fake_malware.exe" + }, + "accessed": 1682752652103, + "created": 1682752652103, + "hash": { + "md5": "fake file md5", + "sha1": "fake file sha1", + "sha256": "fake file sha256" + }, + "mtime": 1682752652103, + "name": "fake_malware.exe", + "owner": "SYSTEM", + "path": "C:/fake_malware.exe", + "size": 3456 + }, + "user": { + "name": "user1" + }, + "host": { + "architecture": "wtnozeqvub", + "hostname": "Host-fwarau82er", + "id": "4260adf9-5e63-445d-92c6-e03359bcd342", + "ip": [ + "10.249.37.72", + "10.150.39.243", + "10.186.17.170" + ], + "mac": [ + "f5-f-97-dc-20-67", + "b5-56-ca-98-81-ca", + "22-86-39-4c-87-33" + ], + "name": "Host-fwarau82er", + "os": { + "Ext": { + "variant": "Darwin" + }, + "family": "Darwin", + "full": "macOS Monterey", + "name": "macOS", + "platform": "macOS", + "version": "12.6.1" + } + }, + "kibana.alert.ancestors": [ + { + "depth": 0, + "id": "vT9cwocBh3b8EMpD8lsi", + "index": ".ds-logs-endpoint.alerts-default-2023.04.27-000001", + "type": "event" + } + ], + "kibana.alert.depth": 1, + "kibana.alert.last_detected": "2023-04-27T11:03:57.993Z", + "kibana.alert.original_event.action": "creation", + "kibana.alert.original_event.agent_id_status": "auth_metadata_missing", + "kibana.alert.original_event.category": "malware", + "kibana.alert.original_event.code": "malicious_file", + "kibana.alert.original_event.dataset": "endpoint", + "kibana.alert.original_event.id": "b28993d4-8b8a-4f0f-9f54-84a89bad66ae", + "kibana.alert.original_event.ingested": "2023-04-27T10:58:03Z", + "kibana.alert.original_event.kind": "alert", + "kibana.alert.original_event.module": "endpoint", + "kibana.alert.original_event.sequence": 5826, + "kibana.alert.original_event.type": "creation", + "kibana.alert.original_time": "2023-04-29T07:17:32.103Z", + "kibana.alert.reason": "malware event with process malware writer, file fake_malware.exe, on Host-fwarau82er created medium alert Endpoint Security.", + "kibana.alert.risk_score": 47, + "kibana.alert.rule.actions": [ + ], + "kibana.alert.rule.author": [ + "Elastic" + ], + "kibana.alert.rule.category": "Custom Query Rule", + "kibana.alert.rule.consumer": "siem", + "kibana.alert.rule.created_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.created_by": "elastic", + "kibana.alert.rule.description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "kibana.alert.rule.enabled": true, + "kibana.alert.rule.exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "kibana.alert.rule.execution.uuid": "ebf843ff-e0e1-47f8-9ed2-cc8066afbcef", + "kibana.alert.rule.false_positives": [ + ], + "kibana.alert.rule.from": "now-10m", + "kibana.alert.rule.immutable": true, + "kibana.alert.rule.indices": [ + "logs-endpoint.alerts-*" + ], + "kibana.alert.rule.interval": "5m", + "kibana.alert.rule.license": "Elastic License v2", + "kibana.alert.rule.max_signals": 10000, + "kibana.alert.rule.name": "Endpoint Security", + "kibana.alert.rule.parameters": { + "author": [ + "Elastic" + ], + "description": "Generates a detection alert each time an Elastic Endpoint Security alert is received. Enabling this rule allows you to immediately begin investigating your Endpoint alerts.", + "exceptions_list": [ + { + "id": "endpoint_list", + "list_id": "endpoint_list", + "namespace_type": "agnostic", + "type": "endpoint" + } + ], + "false_positives": [ + ], + "from": "now-10m", + "immutable": true, + "index": [ + "logs-endpoint.alerts-*" + ], + "language": "kuery", + "license": "Elastic License v2", + "max_signals": 10000, + "query": "event.kind:alert and event.module:(endpoint and not endgame)\n", + "references": [ + ], + "related_integrations": [ + { + "package": "endpoint", + "version": "^8.2.0" + } + ], + "required_fields": [ + { + "ecs": true, + "name": "event.kind", + "type": "keyword" + }, + { + "ecs": true, + "name": "event.module", + "type": "keyword" + } + ], + "risk_score": 47, + "risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "rule_name_override": "message", + "setup": "", + "severity": "medium", + "severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "threat": [ + ], + "timestamp_override": "event.ingested", + "to": "now", + "type": "query", + "version": 101 + }, + "kibana.alert.rule.producer": "siem", + "kibana.alert.rule.references": [ + ], + "kibana.alert.rule.revision": 0, + "kibana.alert.rule.risk_score": 47, + "kibana.alert.rule.risk_score_mapping": [ + { + "field": "event.risk_score", + "operator": "equals", + "value": "" + } + ], + "kibana.alert.rule.rule_id": "9a1a2dae-0b5f-4c3d-8305-a268d404c306", + "kibana.alert.rule.rule_name_override": "message", + "kibana.alert.rule.rule_type_id": "siem.queryRule", + "kibana.alert.rule.severity": "medium", + "kibana.alert.rule.severity_mapping": [ + { + "field": "event.severity", + "operator": "equals", + "severity": "low", + "value": "21" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "medium", + "value": "47" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "high", + "value": "73" + }, + { + "field": "event.severity", + "operator": "equals", + "severity": "critical", + "value": "99" + } + ], + "kibana.alert.rule.tags": [ + "Elastic", + "Endpoint Security" + ], + "kibana.alert.rule.threat": [ + ], + "kibana.alert.rule.timestamp_override": "event.ingested", + "kibana.alert.rule.to": "now", + "kibana.alert.rule.type": "query", + "kibana.alert.rule.updated_at": "2023-04-27T10:58:27.546Z", + "kibana.alert.rule.updated_by": "elastic", + "kibana.alert.rule.uuid": "7015a3e2-e4ea-11ed-8c11-49608884878f", + "kibana.alert.rule.version": 101, + "kibana.alert.severity": "medium", + "kibana.alert.start": "2023-04-27T11:03:57.993Z", + "kibana.alert.status": "active", + "kibana.alert.url": "http://localhost:5601/app/security/alerts/redirect/eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1?index=.alerts-security.alerts-default×tamp=2023-04-27T11:03:57.906Z", + "kibana.alert.uuid": "eabbdefc23da981f2b74ab58b82622a97bb9878caa11bc914e2adfacc94780f1", + "kibana.alert.workflow_status": "open", + "kibana.space_ids": [ + "default" + ], + "kibana.version": "8.8.0", + "process": { + "Ext": { + "ancestry": [ + "qa5jgw1wr7", + "5k1hclygc6" + ], + "code_signature": [ + { + "subject_name": "bad signer", + "trusted": false + } + ], + "token": { + "domain": "NT AUTHORITY", + "integrity_level": 16384, + "integrity_level_name": "system", + "privileges": [ + { + "description": "Replace a process level token", + "enabled": false, + "name": "SeAssignPrimaryTokenPrivilege" + } + ], + "sid": "S-1-5-18", + "type": "tokenPrimary", + "user": "SYSTEM" + }, + "user": "SYSTEM" + }, + "entity_id": "nqh8ts6ves", + "entry_leader": { + "entity_id": "jnm38bel0w", + "name": "fake entry", + "pid": 791 + }, + "executable": "C:/malware.exe", + "group_leader": { + "entity_id": "jnm38bel0w", + "name": "fake leader", + "pid": 848 + }, + "hash": { + "md5": "fake md5", + "sha1": "fake sha1", + "sha256": "fake sha256" + }, + "name": "malware writer", + "parent": { + "entity_id": "qa5jgw1wr7", + "pid": 1 + }, + "pid": 2, + "session_leader": { + "entity_id": "jnm38bel0w", + "name": "fake session", + "pid": 909 + }, + "start": 1682752652103, + "uptime": 0 + } + } + } +} \ No newline at end of file diff --git a/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/mappings.json b/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/mappings.json new file mode 100644 index 000000000000..f5a6e53cc4d6 --- /dev/null +++ b/x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs/mappings.json @@ -0,0 +1,7900 @@ +{ + "type": "index", + "value": { + "aliases": { + ".alerts-security.alerts-default": { + "is_write_index": true + }, + ".siem-signals-default": { + "is_write_index": false + } + }, + "index": ".internal.alerts-security.alerts-default-000001", + "mappings": { + "_meta": { + "kibana": { + "version": "8.8.0" + }, + "managed": true, + "namespace": "default" + }, + "dynamic": "false", + "properties": { + "@timestamp": { + "type": "date" + }, + "agent": { + "properties": { + "build": { + "properties": { + "original": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "client": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "cloud": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "origin": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "target": { + "properties": { + "account": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "availability_zone": { + "ignore_above": 1024, + "type": "keyword" + }, + "instance": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "machine": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "project": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "region": { + "ignore_above": 1024, + "type": "keyword" + }, + "service": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "container": { + "properties": { + "cpu": { + "properties": { + "usage": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "disk": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "write": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "image": { + "properties": { + "hash": { + "properties": { + "all": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "tag": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "labels": { + "type": "object" + }, + "memory": { + "properties": { + "usage": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "egress": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "ingress": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "runtime": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "destination": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "device": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "manufacturer": { + "ignore_above": 1024, + "type": "keyword" + }, + "model": { + "properties": { + "identifier": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dll": { + "properties": { + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "dns": { + "properties": { + "answers": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "ttl": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "header_flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "op_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "question": { + "properties": { + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "resolved_ip": { + "type": "ip" + }, + "response_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ecs": { + "properties": { + "version": { + "type": "keyword" + } + } + }, + "email": { + "properties": { + "attachments": { + "properties": { + "file": { + "properties": { + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + } + } + } + }, + "type": "nested" + }, + "bcc": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cc": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "content_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "delivery_timestamp": { + "type": "date" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "from": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "local_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message_id": { + "type": "wildcard" + }, + "origination_timestamp": { + "type": "date" + }, + "reply_to": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "sender": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "subject": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "to": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "x_mailer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "error": { + "properties": { + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "message": { + "type": "match_only_text" + }, + "stack_trace": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "event": { + "properties": { + "action": { + "type": "keyword" + }, + "agent_id_status": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "code": { + "ignore_above": 1024, + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "ignore_above": 1024, + "type": "keyword" + }, + "duration": { + "type": "long" + }, + "end": { + "type": "date" + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "type": "keyword" + }, + "module": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "type": "keyword" + }, + "outcome": { + "ignore_above": 1024, + "type": "keyword" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reason": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "faas": { + "properties": { + "coldstart": { + "type": "boolean" + }, + "execution": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "trigger": { + "properties": { + "request_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fork_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "host": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "boot": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "cpu": { + "properties": { + "usage": { + "scaling_factor": 1000, + "type": "scaled_float" + } + } + }, + "disk": { + "properties": { + "read": { + "properties": { + "bytes": { + "type": "long" + } + } + }, + "write": { + "properties": { + "bytes": { + "type": "long" + } + } + } + } + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "network": { + "properties": { + "egress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + }, + "ingress": { + "properties": { + "bytes": { + "type": "long" + }, + "packets": { + "type": "long" + } + } + } + } + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pid_ns_ino": { + "ignore_above": 1024, + "type": "keyword" + }, + "risk": { + "properties": { + "calculated_level": { + "ignore_above": 1024, + "type": "keyword" + }, + "calculated_score": { + "type": "float" + }, + "calculated_score_norm": { + "type": "float" + }, + "static_level": { + "ignore_above": 1024, + "type": "keyword" + }, + "static_score": { + "type": "float" + }, + "static_score_norm": { + "type": "float" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uptime": { + "type": "long" + } + } + }, + "http": { + "properties": { + "request": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + } + } + }, + "bytes": { + "type": "long" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "method": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "referrer": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "response": { + "properties": { + "body": { + "properties": { + "bytes": { + "type": "long" + }, + "content": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + } + } + }, + "bytes": { + "type": "long" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "status_code": { + "type": "long" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "kibana": { + "properties": { + "alert": { + "properties": { + "action_group": { + "type": "keyword" + }, + "ancestors": { + "properties": { + "depth": { + "type": "long" + }, + "id": { + "type": "keyword" + }, + "index": { + "type": "keyword" + }, + "rule": { + "type": "keyword" + }, + "type": { + "type": "keyword" + } + } + }, + "building_block_type": { + "type": "keyword" + }, + "case_ids": { + "type": "keyword" + }, + "depth": { + "type": "long" + }, + "duration": { + "properties": { + "us": { + "type": "long" + } + } + }, + "end": { + "type": "date" + }, + "flapping": { + "type": "boolean" + }, + "flapping_history": { + "type": "boolean" + }, + "group": { + "properties": { + "id": { + "type": "keyword" + }, + "index": { + "type": "integer" + } + } + }, + "instance": { + "properties": { + "id": { + "type": "keyword" + } + } + }, + "last_detected": { + "type": "date" + }, + "maintenance_window_ids": { + "type": "keyword" + }, + "new_terms": { + "type": "keyword" + }, + "original_event": { + "properties": { + "action": { + "type": "keyword" + }, + "agent_id_status": { + "type": "keyword" + }, + "category": { + "type": "keyword" + }, + "code": { + "type": "keyword" + }, + "created": { + "type": "date" + }, + "dataset": { + "type": "keyword" + }, + "duration": { + "type": "keyword" + }, + "end": { + "type": "date" + }, + "hash": { + "type": "keyword" + }, + "id": { + "type": "keyword" + }, + "ingested": { + "type": "date" + }, + "kind": { + "type": "keyword" + }, + "module": { + "type": "keyword" + }, + "original": { + "type": "keyword" + }, + "outcome": { + "type": "keyword" + }, + "provider": { + "type": "keyword" + }, + "reason": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "risk_score_norm": { + "type": "float" + }, + "sequence": { + "type": "long" + }, + "severity": { + "type": "long" + }, + "start": { + "type": "date" + }, + "timezone": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "url": { + "type": "keyword" + } + } + }, + "original_time": { + "type": "date" + }, + "reason": { + "type": "keyword" + }, + "risk_score": { + "type": "float" + }, + "rule": { + "properties": { + "author": { + "type": "keyword" + }, + "building_block_type": { + "type": "keyword" + }, + "category": { + "type": "keyword" + }, + "consumer": { + "type": "keyword" + }, + "created_at": { + "type": "date" + }, + "created_by": { + "type": "keyword" + }, + "description": { + "type": "keyword" + }, + "enabled": { + "type": "keyword" + }, + "exceptions_list": { + "type": "object" + }, + "execution": { + "properties": { + "uuid": { + "type": "keyword" + } + } + }, + "false_positives": { + "type": "keyword" + }, + "from": { + "type": "keyword" + }, + "immutable": { + "type": "keyword" + }, + "interval": { + "type": "keyword" + }, + "license": { + "type": "keyword" + }, + "max_signals": { + "type": "long" + }, + "name": { + "type": "keyword" + }, + "note": { + "type": "keyword" + }, + "parameters": { + "ignore_above": 4096, + "type": "flattened" + }, + "producer": { + "type": "keyword" + }, + "references": { + "type": "keyword" + }, + "revision": { + "type": "long" + }, + "rule_id": { + "type": "keyword" + }, + "rule_name_override": { + "type": "keyword" + }, + "rule_type_id": { + "type": "keyword" + }, + "tags": { + "type": "keyword" + }, + "threat": { + "properties": { + "framework": { + "type": "keyword" + }, + "tactic": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + }, + "subtechnique": { + "properties": { + "id": { + "type": "keyword" + }, + "name": { + "type": "keyword" + }, + "reference": { + "type": "keyword" + } + } + } + } + } + } + }, + "timeline_id": { + "type": "keyword" + }, + "timeline_title": { + "type": "keyword" + }, + "timestamp_override": { + "type": "keyword" + }, + "to": { + "type": "keyword" + }, + "type": { + "type": "keyword" + }, + "updated_at": { + "type": "date" + }, + "updated_by": { + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "version": { + "type": "keyword" + } + } + }, + "severity": { + "type": "keyword" + }, + "start": { + "type": "date" + }, + "status": { + "type": "keyword" + }, + "suppression": { + "properties": { + "docs_count": { + "type": "long" + }, + "end": { + "type": "date" + }, + "start": { + "type": "date" + }, + "terms": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } + } + } + }, + "system_status": { + "type": "keyword" + }, + "threshold_result": { + "properties": { + "cardinality": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "long" + } + } + }, + "count": { + "type": "long" + }, + "from": { + "type": "date" + }, + "terms": { + "properties": { + "field": { + "type": "keyword" + }, + "value": { + "type": "keyword" + } + } + } + } + }, + "time_range": { + "format": "epoch_millis||strict_date_optional_time", + "type": "date_range" + }, + "url": { + "ignore_above": 2048, + "index": false, + "type": "keyword" + }, + "uuid": { + "type": "keyword" + }, + "workflow_reason": { + "type": "keyword" + }, + "workflow_status": { + "type": "keyword" + }, + "workflow_user": { + "type": "keyword" + } + } + }, + "space_ids": { + "type": "keyword" + }, + "version": { + "type": "version" + } + } + }, + "labels": { + "type": "object" + }, + "log": { + "properties": { + "file": { + "properties": { + "path": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "level": { + "ignore_above": 1024, + "type": "keyword" + }, + "logger": { + "ignore_above": 1024, + "type": "keyword" + }, + "origin": { + "properties": { + "file": { + "properties": { + "line": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "function": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "syslog": { + "properties": { + "appname": { + "ignore_above": 1024, + "type": "keyword" + }, + "facility": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "msgid": { + "ignore_above": 1024, + "type": "keyword" + }, + "priority": { + "type": "long" + }, + "procid": { + "ignore_above": 1024, + "type": "keyword" + }, + "severity": { + "properties": { + "code": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "structured_data": { + "type": "flattened" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "message": { + "type": "match_only_text" + }, + "network": { + "properties": { + "application": { + "ignore_above": 1024, + "type": "keyword" + }, + "bytes": { + "type": "long" + }, + "community_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "direction": { + "ignore_above": 1024, + "type": "keyword" + }, + "forwarded_ip": { + "type": "ip" + }, + "iana_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "inner": { + "properties": { + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "packets": { + "type": "long" + }, + "protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "transport": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "observer": { + "properties": { + "egress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hostname": { + "ignore_above": 1024, + "type": "keyword" + }, + "ingress": { + "properties": { + "interface": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vlan": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "zone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "vendor": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "orchestrator": { + "properties": { + "api_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "cluster": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "namespace": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "resource": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "organization": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "package": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "build_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "checksum": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "install_scope": { + "ignore_above": 1024, + "type": "keyword" + }, + "installed": { + "type": "date" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "process": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "end": { + "type": "date" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "entry_leader": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "attested_groups": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "attested_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "command_line": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "entry_meta": { + "properties": { + "source": { + "properties": { + "ip": { + "type": "ip" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interactive": { + "type": "boolean" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "session_leader": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start": { + "type": "date" + } + } + }, + "start": { + "type": "date" + } + } + }, + "pid": { + "type": "long" + }, + "real_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "same_as_process": { + "type": "boolean" + }, + "saved_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "start": { + "type": "date" + }, + "supplemental_groups": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tty": { + "properties": { + "char_device": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "working_directory": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "env_vars": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "group_leader": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interactive": { + "type": "boolean" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "real_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "same_as_process": { + "type": "boolean" + }, + "saved_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "start": { + "type": "date" + }, + "supplemental_groups": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tty": { + "properties": { + "char_device": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "working_directory": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interactive": { + "type": "boolean" + }, + "io": { + "properties": { + "bytes_skipped": { + "properties": { + "length": { + "type": "long" + }, + "offset": { + "type": "long" + } + } + }, + "max_bytes_per_process_exceeded": { + "type": "boolean" + }, + "text": { + "type": "wildcard" + }, + "total_bytes_captured": { + "type": "long" + }, + "total_bytes_skipped": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "command_line": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "end": { + "type": "date" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "exit_code": { + "type": "long" + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "group_leader": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start": { + "type": "date" + } + } + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interactive": { + "type": "boolean" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "real_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "start": { + "type": "date" + }, + "supplemental_groups": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "properties": { + "char_device": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + } + } + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "working_directory": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "pgid": { + "type": "long" + }, + "pid": { + "type": "long" + }, + "previous": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "session_leader": { + "properties": { + "args": { + "ignore_above": 1024, + "type": "keyword" + }, + "args_count": { + "type": "long" + }, + "command_line": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "executable": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "interactive": { + "type": "boolean" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "parent": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "session_leader": { + "properties": { + "entity_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "pid": { + "type": "long" + }, + "start": { + "type": "date" + } + } + }, + "start": { + "type": "date" + } + } + }, + "pid": { + "type": "long" + }, + "real_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "real_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "same_as_process": { + "type": "boolean" + }, + "saved_group": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "saved_user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "start": { + "type": "date" + }, + "supplemental_groups": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tty": { + "properties": { + "char_device": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + } + } + }, + "user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "working_directory": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "start": { + "type": "date" + }, + "supplemental_groups": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "thread": { + "properties": { + "id": { + "type": "long" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "title": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "tty": { + "properties": { + "char_device": { + "properties": { + "major": { + "type": "long" + }, + "minor": { + "type": "long" + } + } + }, + "columns": { + "type": "long" + }, + "rows": { + "type": "long" + } + } + }, + "uptime": { + "type": "long" + }, + "user": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "working_directory": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "related": { + "properties": { + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "hosts": { + "ignore_above": 1024, + "type": "keyword" + }, + "ip": { + "type": "ip" + }, + "user": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "rule": { + "properties": { + "author": { + "ignore_above": 1024, + "type": "keyword" + }, + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "license": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "ruleset": { + "ignore_above": 1024, + "type": "keyword" + }, + "uuid": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "server": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "service": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "origin": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "environment": { + "ignore_above": 1024, + "type": "keyword" + }, + "ephemeral_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "node": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "role": { + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "state": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "signal": { + "properties": { + "ancestors": { + "properties": { + "depth": { + "path": "kibana.alert.ancestors.depth", + "type": "alias" + }, + "id": { + "path": "kibana.alert.ancestors.id", + "type": "alias" + }, + "index": { + "path": "kibana.alert.ancestors.index", + "type": "alias" + }, + "type": { + "path": "kibana.alert.ancestors.type", + "type": "alias" + } + } + }, + "depth": { + "path": "kibana.alert.depth", + "type": "alias" + }, + "group": { + "properties": { + "id": { + "path": "kibana.alert.group.id", + "type": "alias" + }, + "index": { + "path": "kibana.alert.group.index", + "type": "alias" + } + } + }, + "original_event": { + "properties": { + "action": { + "path": "kibana.alert.original_event.action", + "type": "alias" + }, + "category": { + "path": "kibana.alert.original_event.category", + "type": "alias" + }, + "code": { + "path": "kibana.alert.original_event.code", + "type": "alias" + }, + "created": { + "path": "kibana.alert.original_event.created", + "type": "alias" + }, + "dataset": { + "path": "kibana.alert.original_event.dataset", + "type": "alias" + }, + "duration": { + "path": "kibana.alert.original_event.duration", + "type": "alias" + }, + "end": { + "path": "kibana.alert.original_event.end", + "type": "alias" + }, + "hash": { + "path": "kibana.alert.original_event.hash", + "type": "alias" + }, + "id": { + "path": "kibana.alert.original_event.id", + "type": "alias" + }, + "kind": { + "path": "kibana.alert.original_event.kind", + "type": "alias" + }, + "module": { + "path": "kibana.alert.original_event.module", + "type": "alias" + }, + "outcome": { + "path": "kibana.alert.original_event.outcome", + "type": "alias" + }, + "provider": { + "path": "kibana.alert.original_event.provider", + "type": "alias" + }, + "reason": { + "path": "kibana.alert.original_event.reason", + "type": "alias" + }, + "risk_score": { + "path": "kibana.alert.original_event.risk_score", + "type": "alias" + }, + "risk_score_norm": { + "path": "kibana.alert.original_event.risk_score_norm", + "type": "alias" + }, + "sequence": { + "path": "kibana.alert.original_event.sequence", + "type": "alias" + }, + "severity": { + "path": "kibana.alert.original_event.severity", + "type": "alias" + }, + "start": { + "path": "kibana.alert.original_event.start", + "type": "alias" + }, + "timezone": { + "path": "kibana.alert.original_event.timezone", + "type": "alias" + }, + "type": { + "path": "kibana.alert.original_event.type", + "type": "alias" + } + } + }, + "original_time": { + "path": "kibana.alert.original_time", + "type": "alias" + }, + "reason": { + "path": "kibana.alert.reason", + "type": "alias" + }, + "rule": { + "properties": { + "author": { + "path": "kibana.alert.rule.author", + "type": "alias" + }, + "building_block_type": { + "path": "kibana.alert.building_block_type", + "type": "alias" + }, + "created_at": { + "path": "kibana.alert.rule.created_at", + "type": "alias" + }, + "created_by": { + "path": "kibana.alert.rule.created_by", + "type": "alias" + }, + "description": { + "path": "kibana.alert.rule.description", + "type": "alias" + }, + "enabled": { + "path": "kibana.alert.rule.enabled", + "type": "alias" + }, + "false_positives": { + "path": "kibana.alert.rule.false_positives", + "type": "alias" + }, + "from": { + "path": "kibana.alert.rule.from", + "type": "alias" + }, + "id": { + "path": "kibana.alert.rule.uuid", + "type": "alias" + }, + "immutable": { + "path": "kibana.alert.rule.immutable", + "type": "alias" + }, + "interval": { + "path": "kibana.alert.rule.interval", + "type": "alias" + }, + "license": { + "path": "kibana.alert.rule.license", + "type": "alias" + }, + "max_signals": { + "path": "kibana.alert.rule.max_signals", + "type": "alias" + }, + "name": { + "path": "kibana.alert.rule.name", + "type": "alias" + }, + "note": { + "path": "kibana.alert.rule.note", + "type": "alias" + }, + "references": { + "path": "kibana.alert.rule.references", + "type": "alias" + }, + "risk_score": { + "path": "kibana.alert.risk_score", + "type": "alias" + }, + "rule_id": { + "path": "kibana.alert.rule.rule_id", + "type": "alias" + }, + "rule_name_override": { + "path": "kibana.alert.rule.rule_name_override", + "type": "alias" + }, + "severity": { + "path": "kibana.alert.severity", + "type": "alias" + }, + "tags": { + "path": "kibana.alert.rule.tags", + "type": "alias" + }, + "threat": { + "properties": { + "framework": { + "path": "kibana.alert.rule.threat.framework", + "type": "alias" + }, + "tactic": { + "properties": { + "id": { + "path": "kibana.alert.rule.threat.tactic.id", + "type": "alias" + }, + "name": { + "path": "kibana.alert.rule.threat.tactic.name", + "type": "alias" + }, + "reference": { + "path": "kibana.alert.rule.threat.tactic.reference", + "type": "alias" + } + } + }, + "technique": { + "properties": { + "id": { + "path": "kibana.alert.rule.threat.technique.id", + "type": "alias" + }, + "name": { + "path": "kibana.alert.rule.threat.technique.name", + "type": "alias" + }, + "reference": { + "path": "kibana.alert.rule.threat.technique.reference", + "type": "alias" + }, + "subtechnique": { + "properties": { + "id": { + "path": "kibana.alert.rule.threat.technique.subtechnique.id", + "type": "alias" + }, + "name": { + "path": "kibana.alert.rule.threat.technique.subtechnique.name", + "type": "alias" + }, + "reference": { + "path": "kibana.alert.rule.threat.technique.subtechnique.reference", + "type": "alias" + } + } + } + } + } + } + }, + "timeline_id": { + "path": "kibana.alert.rule.timeline_id", + "type": "alias" + }, + "timeline_title": { + "path": "kibana.alert.rule.timeline_title", + "type": "alias" + }, + "timestamp_override": { + "path": "kibana.alert.rule.timestamp_override", + "type": "alias" + }, + "to": { + "path": "kibana.alert.rule.to", + "type": "alias" + }, + "type": { + "path": "kibana.alert.rule.type", + "type": "alias" + }, + "updated_at": { + "path": "kibana.alert.rule.updated_at", + "type": "alias" + }, + "updated_by": { + "path": "kibana.alert.rule.updated_by", + "type": "alias" + }, + "version": { + "path": "kibana.alert.rule.version", + "type": "alias" + } + } + }, + "status": { + "path": "kibana.alert.workflow_status", + "type": "alias" + }, + "threshold_result": { + "properties": { + "cardinality": { + "properties": { + "field": { + "path": "kibana.alert.threshold_result.cardinality.field", + "type": "alias" + }, + "value": { + "path": "kibana.alert.threshold_result.cardinality.value", + "type": "alias" + } + } + }, + "count": { + "path": "kibana.alert.threshold_result.count", + "type": "alias" + }, + "from": { + "path": "kibana.alert.threshold_result.from", + "type": "alias" + }, + "terms": { + "properties": { + "field": { + "path": "kibana.alert.threshold_result.terms.field", + "type": "alias" + }, + "value": { + "path": "kibana.alert.threshold_result.terms.value", + "type": "alias" + } + } + } + } + } + } + }, + "source": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + }, + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "bytes": { + "type": "long" + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "mac": { + "ignore_above": 1024, + "type": "keyword" + }, + "nat": { + "properties": { + "ip": { + "type": "ip" + }, + "port": { + "type": "long" + } + } + }, + "packets": { + "type": "long" + }, + "port": { + "type": "long" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "user": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "span": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tags": { + "type": "keyword" + }, + "threat": { + "properties": { + "enrichments": { + "properties": { + "indicator": { + "properties": { + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "confidence": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fork_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlp_version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "modified_at": { + "type": "date" + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "original": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "type": "wildcard" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "matched": { + "properties": { + "atomic": { + "ignore_above": 1024, + "type": "keyword" + }, + "field": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "index": { + "ignore_above": 1024, + "type": "keyword" + }, + "occurred": { + "type": "date" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + }, + "type": "nested" + }, + "feed": { + "properties": { + "dashboard_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "framework": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "indicator": { + "properties": { + "as": { + "properties": { + "number": { + "type": "long" + }, + "organization": { + "properties": { + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "confidence": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "properties": { + "address": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "file": { + "properties": { + "accessed": { + "type": "date" + }, + "attributes": { + "ignore_above": 1024, + "type": "keyword" + }, + "code_signature": { + "properties": { + "digest_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "exists": { + "type": "boolean" + }, + "signing_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "status": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "team_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "timestamp": { + "type": "date" + }, + "trusted": { + "type": "boolean" + }, + "valid": { + "type": "boolean" + } + } + }, + "created": { + "type": "date" + }, + "ctime": { + "type": "date" + }, + "device": { + "ignore_above": 1024, + "type": "keyword" + }, + "directory": { + "ignore_above": 1024, + "type": "keyword" + }, + "drive_letter": { + "ignore_above": 1, + "type": "keyword" + }, + "elf": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "byte_order": { + "ignore_above": 1024, + "type": "keyword" + }, + "cpu_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "creation_date": { + "type": "date" + }, + "exports": { + "type": "flattened" + }, + "header": { + "properties": { + "abi_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "class": { + "ignore_above": 1024, + "type": "keyword" + }, + "data": { + "ignore_above": 1024, + "type": "keyword" + }, + "entrypoint": { + "type": "long" + }, + "object_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "os_abi": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "imports": { + "type": "flattened" + }, + "sections": { + "properties": { + "chi2": { + "type": "long" + }, + "entropy": { + "type": "long" + }, + "flags": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_offset": { + "ignore_above": 1024, + "type": "keyword" + }, + "physical_size": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "virtual_address": { + "type": "long" + }, + "virtual_size": { + "type": "long" + } + }, + "type": "nested" + }, + "segments": { + "properties": { + "sections": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + }, + "type": "nested" + }, + "shared_libraries": { + "ignore_above": 1024, + "type": "keyword" + }, + "telfhash": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fork_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "gid": { + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha384": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha512": { + "ignore_above": 1024, + "type": "keyword" + }, + "ssdeep": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlsh": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "inode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mime_type": { + "ignore_above": 1024, + "type": "keyword" + }, + "mode": { + "ignore_above": 1024, + "type": "keyword" + }, + "mtime": { + "type": "date" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "owner": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "pe": { + "properties": { + "architecture": { + "ignore_above": 1024, + "type": "keyword" + }, + "company": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "ignore_above": 1024, + "type": "keyword" + }, + "file_version": { + "ignore_above": 1024, + "type": "keyword" + }, + "imphash": { + "ignore_above": 1024, + "type": "keyword" + }, + "original_file_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "pehash": { + "ignore_above": 1024, + "type": "keyword" + }, + "product": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "size": { + "type": "long" + }, + "target_path": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "uid": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "first_seen": { + "type": "date" + }, + "geo": { + "properties": { + "city_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "continent_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "country_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "location": { + "type": "geo_point" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "postal_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_iso_code": { + "ignore_above": 1024, + "type": "keyword" + }, + "region_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "timezone": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "ip": { + "type": "ip" + }, + "last_seen": { + "type": "date" + }, + "marking": { + "properties": { + "tlp": { + "ignore_above": 1024, + "type": "keyword" + }, + "tlp_version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "modified_at": { + "type": "date" + }, + "port": { + "type": "long" + }, + "provider": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "registry": { + "properties": { + "data": { + "properties": { + "bytes": { + "ignore_above": 1024, + "type": "keyword" + }, + "strings": { + "type": "wildcard" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hive": { + "ignore_above": 1024, + "type": "keyword" + }, + "key": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "ignore_above": 1024, + "type": "keyword" + }, + "value": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "scanner_stats": { + "type": "long" + }, + "sightings": { + "type": "long" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "original": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "type": "wildcard" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "software": { + "properties": { + "alias": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "platforms": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "tactic": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "technique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "subtechnique": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + } + } + }, + "tls": { + "properties": { + "cipher": { + "ignore_above": 1024, + "type": "keyword" + }, + "client": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "server_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "supported_ciphers": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "established": { + "type": "boolean" + }, + "next_protocol": { + "ignore_above": 1024, + "type": "keyword" + }, + "resumed": { + "type": "boolean" + }, + "server": { + "properties": { + "certificate": { + "ignore_above": 1024, + "type": "keyword" + }, + "certificate_chain": { + "ignore_above": 1024, + "type": "keyword" + }, + "hash": { + "properties": { + "md5": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha1": { + "ignore_above": 1024, + "type": "keyword" + }, + "sha256": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "issuer": { + "ignore_above": 1024, + "type": "keyword" + }, + "ja3s": { + "ignore_above": 1024, + "type": "keyword" + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "subject": { + "ignore_above": 1024, + "type": "keyword" + }, + "x509": { + "properties": { + "alternative_names": { + "ignore_above": 1024, + "type": "keyword" + }, + "issuer": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "not_after": { + "type": "date" + }, + "not_before": { + "type": "date" + }, + "public_key_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_curve": { + "ignore_above": 1024, + "type": "keyword" + }, + "public_key_exponent": { + "type": "long" + }, + "public_key_size": { + "type": "long" + }, + "serial_number": { + "ignore_above": 1024, + "type": "keyword" + }, + "signature_algorithm": { + "ignore_above": 1024, + "type": "keyword" + }, + "subject": { + "properties": { + "common_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "country": { + "ignore_above": 1024, + "type": "keyword" + }, + "distinguished_name": { + "ignore_above": 1024, + "type": "keyword" + }, + "locality": { + "ignore_above": 1024, + "type": "keyword" + }, + "organization": { + "ignore_above": 1024, + "type": "keyword" + }, + "organizational_unit": { + "ignore_above": 1024, + "type": "keyword" + }, + "state_or_province": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version_number": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + }, + "version_protocol": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "trace": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "transaction": { + "properties": { + "id": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "url": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "extension": { + "ignore_above": 1024, + "type": "keyword" + }, + "fragment": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "original": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "type": "wildcard" + }, + "password": { + "ignore_above": 1024, + "type": "keyword" + }, + "path": { + "type": "wildcard" + }, + "port": { + "type": "long" + }, + "query": { + "ignore_above": 1024, + "type": "keyword" + }, + "registered_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "scheme": { + "ignore_above": 1024, + "type": "keyword" + }, + "subdomain": { + "ignore_above": 1024, + "type": "keyword" + }, + "top_level_domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "username": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "user": { + "properties": { + "changes": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "effective": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "risk": { + "properties": { + "calculated_level": { + "ignore_above": 1024, + "type": "keyword" + }, + "calculated_score": { + "type": "float" + }, + "calculated_score_norm": { + "type": "float" + }, + "static_level": { + "ignore_above": 1024, + "type": "keyword" + }, + "static_score": { + "type": "float" + }, + "static_score_norm": { + "type": "float" + } + } + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + }, + "target": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "email": { + "ignore_above": 1024, + "type": "keyword" + }, + "full_name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "group": { + "properties": { + "domain": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "hash": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "roles": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "user_agent": { + "properties": { + "device": { + "properties": { + "name": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "name": { + "ignore_above": 1024, + "type": "keyword" + }, + "original": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "os": { + "properties": { + "family": { + "ignore_above": 1024, + "type": "keyword" + }, + "full": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "kernel": { + "ignore_above": 1024, + "type": "keyword" + }, + "name": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "platform": { + "ignore_above": 1024, + "type": "keyword" + }, + "type": { + "ignore_above": 1024, + "type": "keyword" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "vulnerability": { + "properties": { + "category": { + "ignore_above": 1024, + "type": "keyword" + }, + "classification": { + "ignore_above": 1024, + "type": "keyword" + }, + "description": { + "fields": { + "text": { + "type": "match_only_text" + } + }, + "ignore_above": 1024, + "type": "keyword" + }, + "enumeration": { + "ignore_above": 1024, + "type": "keyword" + }, + "id": { + "ignore_above": 1024, + "type": "keyword" + }, + "reference": { + "ignore_above": 1024, + "type": "keyword" + }, + "report_id": { + "ignore_above": 1024, + "type": "keyword" + }, + "scanner": { + "properties": { + "vendor": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "score": { + "properties": { + "base": { + "type": "float" + }, + "environmental": { + "type": "float" + }, + "temporal": { + "type": "float" + }, + "version": { + "ignore_above": 1024, + "type": "keyword" + } + } + }, + "severity": { + "ignore_above": 1024, + "type": "keyword" + } + } + } + } + }, + "settings": { + "index": { + "auto_expand_replicas": "0-1", + "hidden": "true", + "mapping": { + "total_fields": { + "limit": "2500" + } + }, + "number_of_replicas": "0", + "number_of_shards": "1" + } + } + } +} diff --git a/x-pack/test/functional/page_objects/index.ts b/x-pack/test/functional/page_objects/index.ts index a8ac0895ed25..75f86f764595 100644 --- a/x-pack/test/functional/page_objects/index.ts +++ b/x-pack/test/functional/page_objects/index.ts @@ -48,6 +48,7 @@ import { StatusPageObject } from './status_page'; import { TagManagementPageObject } from './tag_management_page'; import { UpgradeAssistantPageObject } from './upgrade_assistant_page'; import { UptimePageObject } from './uptime_page'; +import { UserProfilePageProvider } from './user_profile_page'; import { WatcherPageObject } from './watcher_page'; // just like services, PageObjects are defined as a map of @@ -95,5 +96,6 @@ export const pageObjects = { tagManagement: TagManagementPageObject, upgradeAssistant: UpgradeAssistantPageObject, uptime: UptimePageObject, + userProfiles: UserProfilePageProvider, watcher: WatcherPageObject, }; diff --git a/x-pack/test/functional/page_objects/remote_clusters_page.ts b/x-pack/test/functional/page_objects/remote_clusters_page.ts index b9f24dd1854d..253ba3a27ff0 100644 --- a/x-pack/test/functional/page_objects/remote_clusters_page.ts +++ b/x-pack/test/functional/page_objects/remote_clusters_page.ts @@ -35,7 +35,7 @@ export function RemoteClustersPageProvider({ getService }: FtrProviderContext) { // Complete trust setup await testSubjects.click('setupTrustDoneButton'); - await testSubjects.setCheckbox('remoteClusterTrustCheckbox', 'check'); + await testSubjects.setCheckbox('remoteClusterTrustCheckboxLabel', 'check'); await testSubjects.click('remoteClusterTrustSubmitButton'); }, async getRemoteClustersList() { diff --git a/x-pack/test/functional/page_objects/user_profile_page.ts b/x-pack/test/functional/page_objects/user_profile_page.ts new file mode 100644 index 000000000000..3380c10e2067 --- /dev/null +++ b/x-pack/test/functional/page_objects/user_profile_page.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../ftr_provider_context'; + +export function UserProfilePageProvider({ getService }: FtrProviderContext) { + const testSubjects = getService('testSubjects'); + const find = getService('find'); + const browser = getService('browser'); + const retry = getService('retry'); + + const getThemeTag = async (): Promise => { + return await browser.execute('return __kbnThemeTag__'); + }; + + const getSaveProfileChangesButton = async () => { + return await testSubjects.find('saveProfileChangesButton'); + }; + + const getReloadWindowButton = async () => { + return await testSubjects.find('windowReloadButton'); + }; + + const getThemeKeypadButton = async (option: string) => { + option = option[0].toUpperCase() + option.substring(1).toLowerCase(); + return await testSubjects.find(`themeKeyPadItem${option}`); + }; + + const saveUserProfileChanges = async (): Promise => { + let saveProfileChangesButton; + await retry.try(async () => { + saveProfileChangesButton = await getSaveProfileChangesButton(); + expect(saveProfileChangesButton).not.to.be(null); + await saveProfileChangesButton.click(); + }); + }; + + const changeUserProfileTheme = async (theme: string): Promise => { + const themeModeButton = await getThemeKeypadButton(theme); + expect(themeModeButton).not.to.be(null); + await themeModeButton.click(); + + await saveUserProfileChanges(); + + let reloadWindowButton; + await retry.try(async () => { + reloadWindowButton = await getReloadWindowButton(); + expect(reloadWindowButton).not.to.be(null); + await reloadWindowButton.click(); + }); + }; + + return { + async getThemeKeypadMenu() { + return await find.byCssSelector('.euiKeyPadMenu'); + }, + + async setFullNameInputField(newFullName: string) { + return await testSubjects.setValue('userProfileFullName', newFullName); + }, + + async setEmailInputField(newEmailAddress: string, clearWithKeyboard: boolean = false) { + return await testSubjects.setValue('userProfileEmail', newEmailAddress, { + clearWithKeyboard, + }); + }, + + async getChangePasswordButton() { + return await testSubjects.find('openChangePasswordForm'); + }, + + async setCurrentPasswordField(currentPassword: string) { + return await testSubjects.setValue( + 'editUserChangePasswordCurrentPasswordInput', + currentPassword + ); + }, + + async setNewPasswordField(newPassword: string) { + return await testSubjects.setValue('editUserChangePasswordNewPasswordInput', newPassword); + }, + + async setConfirmPasswordField(newPassword: string) { + return await testSubjects.setValue('editUserChangePasswordConfirmPasswordInput', newPassword); + }, + + async getChangePasswordFormSubmitButton() { + return await testSubjects.find('changePasswordFormSubmitButton'); + }, + getThemeTag, + saveUserProfileChanges, + changeUserProfileTheme, + }; +} diff --git a/x-pack/test/functional/services/aiops/change_point_detection_page.ts b/x-pack/test/functional/services/aiops/change_point_detection_page.ts index 4f83137df472..b4950763194c 100644 --- a/x-pack/test/functional/services/aiops/change_point_detection_page.ts +++ b/x-pack/test/functional/services/aiops/change_point_detection_page.ts @@ -26,7 +26,7 @@ export function ChangePointDetectionPageProvider( const dashboardPage = getPageObject('dashboard'); return { - async navigateToIndexPatternSelection() { + async navigateToDataViewSelection() { await testSubjects.click('mlMainTab changePointDetection'); await testSubjects.existOrFail('mlPageSourceSelection'); }, diff --git a/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts b/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts index 59c786833a53..661881a28838 100644 --- a/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts +++ b/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts @@ -21,7 +21,7 @@ export function LogPatternAnalysisPageProvider({ getService, getPageObject }: Ft }); }, - async navigateToIndexPatternSelection() { + async navigateToDataViewSelection() { await testSubjects.click('mlMainTab logCategorization'); await testSubjects.existOrFail('mlPageSourceSelection'); }, diff --git a/x-pack/test/functional/services/aiops/log_rate_analysis_page.ts b/x-pack/test/functional/services/aiops/log_rate_analysis_page.ts index 510a056ca5c4..ea2251a47588 100644 --- a/x-pack/test/functional/services/aiops/log_rate_analysis_page.ts +++ b/x-pack/test/functional/services/aiops/log_rate_analysis_page.ts @@ -255,7 +255,7 @@ export function LogRateAnalysisPageProvider({ getService, getPageObject }: FtrPr }); }, - async navigateToIndexPatternSelection() { + async navigateToDataViewSelection() { await testSubjects.click('mlMainTab logRateAnalysis'); await testSubjects.existOrFail('mlPageSourceSelection'); }, diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts index beedbb145dce..3580bd2c8529 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts @@ -623,22 +623,22 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( }); }, - async assertCreateIndexPatternSwitchExists() { - await testSubjects.existOrFail(`mlAnalyticsCreateJobWizardCreateIndexPatternCheckbox`, { + async assertCreateDataViewSwitchExists() { + await testSubjects.existOrFail(`mlAnalyticsCreateJobWizardCreateDataViewCheckbox`, { allowHidden: true, }); }, - async getCreateIndexPatternSwitchCheckState(): Promise { + async getCreateDataViewSwitchCheckState(): Promise { const state = await testSubjects.getAttribute( - 'mlAnalyticsCreateJobWizardCreateIndexPatternCheckbox', + 'mlAnalyticsCreateJobWizardCreateDataViewCheckbox', 'checked' ); return state === 'true'; }, - async assertCreateIndexPatternSwitchCheckState(expectedCheckState: boolean) { - const actualCheckState = await this.getCreateIndexPatternSwitchCheckState(); + async assertCreateDataViewSwitchCheckState(expectedCheckState: boolean) { + const actualCheckState = await this.getCreateDataViewSwitchCheckState(); expect(actualCheckState).to.eql( expectedCheckState, `Create data view switch check state should be '${expectedCheckState}' (got '${actualCheckState}')` @@ -674,11 +674,11 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( await this.assertDestIndexSameAsIdCheckState(checkState); }, - async setCreateIndexPatternSwitchState(checkState: boolean) { - if ((await this.getCreateIndexPatternSwitchCheckState()) !== checkState) { - await testSubjects.click('mlAnalyticsCreateJobWizardCreateIndexPatternCheckbox'); + async setCreateDataViewSwitchState(checkState: boolean) { + if ((await this.getCreateDataViewSwitchCheckState()) !== checkState) { + await testSubjects.click('mlAnalyticsCreateJobWizardCreateDataViewCheckbox'); } - await this.assertCreateIndexPatternSwitchCheckState(checkState); + await this.assertCreateDataViewSwitchCheckState(checkState); }, async assertStartJobCheckboxExists() { @@ -755,7 +755,6 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( async assertCreationCalloutMessagesExist() { await testSubjects.existOrFail('analyticsWizardCreationCallout_0'); await testSubjects.existOrFail('analyticsWizardCreationCallout_1'); - await testSubjects.existOrFail('analyticsWizardCreationCallout_2'); }, async navigateToJobManagementPage() { diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts b/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts index a58820ae393b..e05be8d8c768 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_edit.ts @@ -18,7 +18,7 @@ import { MlCustomUrls } from './custom_urls'; export interface DiscoverUrlConfig { label: string; - indexPattern: string; + indexName: string; queryEntityFieldNames: string[]; timeRange: TimeRangeType; timeRangeInterval?: string; @@ -98,7 +98,7 @@ export function MachineLearningDataFrameAnalyticsEditProvider( ); await mlCommonUI.selectSelectValueByVisibleText( 'mlJobCustomUrlDiscoverIndexPatternInput', - customUrl.indexPattern + customUrl.indexName ); await customUrls.setCustomUrlQueryEntityFieldNames(customUrl.queryEntityFieldNames); if (addTimerange) { diff --git a/x-pack/test/functional/services/ml/data_visualizer.ts b/x-pack/test/functional/services/ml/data_visualizer.ts index 3571f9193e6b..cccdeaf07e4f 100644 --- a/x-pack/test/functional/services/ml/data_visualizer.ts +++ b/x-pack/test/functional/services/ml/data_visualizer.ts @@ -55,7 +55,7 @@ export function MachineLearningDataVisualizerProvider({ getService }: FtrProvide ); }, - async navigateToIndexPatternSelection() { + async navigateToDataViewSelection() { await testSubjects.click('mlDataVisualizerSelectIndexButton'); await testSubjects.existOrFail('mlPageSourceSelection'); }, diff --git a/x-pack/test/functional/services/ml/test_resources.ts b/x-pack/test/functional/services/ml/test_resources.ts index 22f43a08f1e7..5035b6844b9c 100644 --- a/x-pack/test/functional/services/ml/test_resources.ts +++ b/x-pack/test/functional/services/ml/test_resources.ts @@ -120,7 +120,7 @@ export function MachineLearningTestResourcesProvider( return savedObjectIds; }, - async getIndexPatternId(title: string, space?: string): Promise { + async getDataViewId(title: string, space?: string): Promise { return this.getSavedObjectIdByTitle(title, SavedObjectType.INDEX_PATTERN, space); }, @@ -136,11 +136,7 @@ export function MachineLearningTestResourcesProvider( return this.getSavedObjectIdByTitle(title, SavedObjectType.DASHBOARD); }, - async createIndexPattern( - title: string, - timeFieldName?: string, - space?: string - ): Promise { + async createDataView(title: string, timeFieldName?: string, space?: string): Promise { log.debug( `Creating index pattern with title '${title}'${ timeFieldName !== undefined ? ` and time field '${timeFieldName}'` : '' @@ -153,7 +149,7 @@ export function MachineLearningTestResourcesProvider( .send({ attributes: { title, timeFieldName } }); mlApi.assertResponseStatusCode(200, status, createResponse); - await this.assertIndexPatternExistByTitle(title, space); + await this.assertDataViewExistByTitle(title, space); log.debug(` > Created with id '${createResponse.id}'`); return createResponse.id; @@ -172,21 +168,21 @@ export function MachineLearningTestResourcesProvider( return createResponse; }, - async createIndexPatternIfNeeded( + async createDataViewIfNeeded( title: string, timeFieldName?: string, space?: string ): Promise { - const indexPatternId = await this.getIndexPatternId(title, space); - if (indexPatternId !== undefined) { + const dataViewId = await this.getDataViewId(title, space); + if (dataViewId !== undefined) { log.debug(`Index pattern with title '${title}' already exists. Nothing to create.`); - return indexPatternId; + return dataViewId; } else { - return await this.createIndexPattern(title, timeFieldName, space); + return await this.createDataView(title, timeFieldName, space); } }, - async assertIndexPatternNotExist(title: string) { + async assertDataViewNotExist(title: string) { await this.assertSavedObjectNotExistsByTitle(title, SavedObjectType.INDEX_PATTERN); }, @@ -218,7 +214,7 @@ export function MachineLearningTestResourcesProvider( return createResponse.id; }, - async createSavedSearchIfNeeded(savedSearch: any, indexPatternTitle: string): Promise { + async createSavedSearchIfNeeded(savedSearch: any, dataViewTitle: string): Promise { const title = savedSearch.requestBody.attributes.title; const savedSearchId = await this.getSavedSearchId(title); if (savedSearchId !== undefined) { @@ -227,24 +223,24 @@ export function MachineLearningTestResourcesProvider( } else { const body = await this.updateSavedSearchRequestBody( savedSearch.requestBody, - indexPatternTitle + dataViewTitle ); return await this.createSavedSearch(title, body); } }, - async updateSavedSearchRequestBody(body: object, indexPatternTitle: string): Promise { - const indexPatternId = await this.getIndexPatternId(indexPatternTitle); - if (indexPatternId === undefined) { + async updateSavedSearchRequestBody(body: object, dataViewTitle: string): Promise { + const dataViewId = await this.getDataViewId(dataViewTitle); + if (dataViewId === undefined) { throw new Error( - `Index pattern '${indexPatternTitle}' to base saved search on does not exist. ` + `Index pattern '${dataViewTitle}' to base saved search on does not exist. ` ); } // inject index pattern id const updatedBody = JSON.parse(JSON.stringify(body), (_key, value) => { if (value === 'INDEX_PATTERN_ID_PLACEHOLDER') { - return indexPatternId; + return dataViewId; } else { return value; } @@ -258,8 +254,8 @@ export function MachineLearningTestResourcesProvider( return updatedBody; }, - async createSavedSearchFarequoteFilterIfNeeded(indexPatternTitle: string = 'ft_farequote') { - await this.createSavedSearchIfNeeded(savedSearches.farequoteFilter, indexPatternTitle); + async createSavedSearchFarequoteFilterIfNeeded(dataViewTitle: string = 'ft_farequote') { + await this.createSavedSearchIfNeeded(savedSearches.farequoteFilter, dataViewTitle); }, async createMLTestDashboardIfNeeded(): Promise { @@ -281,48 +277,37 @@ export function MachineLearningTestResourcesProvider( } }, - async createSavedSearchFarequoteLuceneIfNeeded(indexPatternTitle: string = 'ft_farequote') { - await this.createSavedSearchIfNeeded(savedSearches.farequoteLucene, indexPatternTitle); + async createSavedSearchFarequoteLuceneIfNeeded(dataViewTitle: string = 'ft_farequote') { + await this.createSavedSearchIfNeeded(savedSearches.farequoteLucene, dataViewTitle); }, - async createSavedSearchFarequoteKueryIfNeeded(indexPatternTitle: string = 'ft_farequote') { - await this.createSavedSearchIfNeeded(savedSearches.farequoteKuery, indexPatternTitle); + async createSavedSearchFarequoteKueryIfNeeded(dataViewTitle: string = 'ft_farequote') { + await this.createSavedSearchIfNeeded(savedSearches.farequoteKuery, dataViewTitle); }, async createSavedSearchFarequoteFilterAndLuceneIfNeeded( - indexPatternTitle: string = 'ft_farequote' + dataViewTitle: string = 'ft_farequote' ) { - await this.createSavedSearchIfNeeded( - savedSearches.farequoteFilterAndLucene, - indexPatternTitle - ); + await this.createSavedSearchIfNeeded(savedSearches.farequoteFilterAndLucene, dataViewTitle); }, - async createSavedSearchFarequoteFilterAndKueryIfNeeded( - indexPatternTitle: string = 'ft_farequote' - ) { - await this.createSavedSearchIfNeeded( - savedSearches.farequoteFilterAndKuery, - indexPatternTitle - ); + async createSavedSearchFarequoteFilterAndKueryIfNeeded(dataViewTitle: string = 'ft_farequote') { + await this.createSavedSearchIfNeeded(savedSearches.farequoteFilterAndKuery, dataViewTitle); }, async createSavedSearchFarequoteFilterTwoAndLuceneIfNeeded( - indexPatternTitle: string = 'ft_farequote' + dataViewTitle: string = 'ft_farequote' ) { await this.createSavedSearchIfNeeded( savedSearches.farequoteFilterTwoAndLucene, - indexPatternTitle + dataViewTitle ); }, async createSavedSearchFarequoteFilterTwoAndKueryIfNeeded( - indexPatternTitle: string = 'ft_farequote' + dataViewTitle: string = 'ft_farequote' ) { - await this.createSavedSearchIfNeeded( - savedSearches.farequoteFilterTwoAndKuery, - indexPatternTitle - ); + await this.createSavedSearchIfNeeded(savedSearches.farequoteFilterTwoAndKuery, dataViewTitle); }, async deleteSavedObjectById( @@ -349,19 +334,19 @@ export function MachineLearningTestResourcesProvider( } }, - async deleteIndexPatternByTitle(title: string, space?: string) { + async deleteDataViewByTitle(title: string, space?: string) { log.debug(`Deleting index pattern with title '${title}'...`); - const indexPatternId = await this.getIndexPatternId(title, space); - if (indexPatternId === undefined) { + const dataViewId = await this.getDataViewId(title, space); + if (dataViewId === undefined) { log.debug(`Index pattern with title '${title}' does not exists. Nothing to delete.`); return; } else { - await this.deleteIndexPatternById(indexPatternId, space); + await this.deleteDataViewById(dataViewId, space); } }, - async deleteIndexPatternById(id: string, space?: string) { + async deleteDataViewById(id: string, space?: string) { await this.deleteSavedObjectById(id, SavedObjectType.INDEX_PATTERN, false, space); }, @@ -485,11 +470,11 @@ export function MachineLearningTestResourcesProvider( ); }, - async assertIndexPatternExistByTitle(title: string, space?: string) { + async assertDataViewExistByTitle(title: string, space?: string) { await this.assertSavedObjectExistsByTitle(title, SavedObjectType.INDEX_PATTERN, space); }, - async assertIndexPatternExistById(id: string) { + async assertDataViewExistById(id: string) { await this.assertSavedObjectExistsById(id, SavedObjectType.INDEX_PATTERN); }, diff --git a/x-pack/test/functional_basic/apps/ml/data_visualizer/group1/index.ts b/x-pack/test/functional_basic/apps/ml/data_visualizer/group1/index.ts index 37295dda128a..cf8f8ed7db84 100644 --- a/x-pack/test/functional_basic/apps/ml/data_visualizer/group1/index.ts +++ b/x-pack/test/functional_basic/apps/ml/data_visualizer/group1/index.ts @@ -25,8 +25,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/module_sample_ecommerce'); diff --git a/x-pack/test/functional_basic/apps/ml/data_visualizer/group2/index.ts b/x-pack/test/functional_basic/apps/ml/data_visualizer/group2/index.ts index e1ed6d554a39..c4205e1bffd6 100644 --- a/x-pack/test/functional_basic/apps/ml/data_visualizer/group2/index.ts +++ b/x-pack/test/functional_basic/apps/ml/data_visualizer/group2/index.ts @@ -25,8 +25,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/module_sample_ecommerce'); diff --git a/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index.ts b/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index.ts index 18a5dfaec2d6..d2e77f952285 100644 --- a/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index.ts +++ b/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index.ts @@ -25,8 +25,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/module_sample_ecommerce'); diff --git a/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index_data_visualizer_actions_panel.ts b/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index_data_visualizer_actions_panel.ts index f8e2c83a1afd..62cbc2e41e36 100644 --- a/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index_data_visualizer_actions_panel.ts +++ b/x-pack/test/functional_basic/apps/ml/data_visualizer/group3/index_data_visualizer_actions_panel.ts @@ -20,7 +20,7 @@ export default function ({ getService }: FtrProviderContext) { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); - await ml.testResources.createIndexPatternIfNeeded(indexPatternName, '@timestamp'); + await ml.testResources.createDataViewIfNeeded(indexPatternName, '@timestamp'); await ml.testResources.createSavedSearchFarequoteKueryIfNeeded(); await ml.testResources.setKibanaTimeZoneToUTC(); @@ -34,7 +34,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.navigation.navigateToDataVisualizer(); await ml.testExecution.logTestStep('loads the saved search selection page'); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.testExecution.logTestStep('loads the index data visualizer page'); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(savedSearch); diff --git a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts index 0ff4eca82a5c..49b477f9e110 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/module_sample_ecommerce' ); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await ml.testResources.createDataViewIfNeeded(ecIndexPattern, 'order_date'); await ml.securityUI.loginAs(testUser.user); }); @@ -105,7 +105,7 @@ export default function ({ getService }: FtrProviderContext) { it('should display elements on Index Data Visualizer page correctly', async () => { await ml.testExecution.logTestStep('should load an index into the data visualizer page'); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexPattern); await ml.testExecution.logTestStep('should display the time range step'); diff --git a/x-pack/test/functional_basic/apps/ml/permissions/index.ts b/x-pack/test/functional_basic/apps/ml/permissions/index.ts index 53e78b4d08c1..8e72bb7bf51e 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/index.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/index.ts @@ -25,8 +25,8 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { await ml.testResources.deleteSavedSearches(); - await ml.testResources.deleteIndexPatternByTitle('ft_farequote'); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_farequote'); + await ml.testResources.deleteDataViewByTitle('ft_module_sample_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/farequote'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/module_sample_ecommerce'); diff --git a/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts b/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts index c7a3f13d23ed..60554e8b1604 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts @@ -36,7 +36,7 @@ export default function ({ getService }: FtrProviderContext) { await esArchiver.loadIfNeeded( 'x-pack/test/functional/es_archives/ml/module_sample_ecommerce' ); - await ml.testResources.createIndexPatternIfNeeded(ecIndexPattern, 'order_date'); + await ml.testResources.createDataViewIfNeeded(ecIndexPattern, 'order_date'); await ml.securityUI.loginAs(testUser.user); }); @@ -105,7 +105,7 @@ export default function ({ getService }: FtrProviderContext) { it('should display elements on Index Data Visualizer page correctly', async () => { await ml.testExecution.logTestStep('should load an index into the data visualizer page'); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(ecIndexPattern); await ml.testExecution.logTestStep('should display the time range step'); diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts index de7a2e42fda0..037e33267dfd 100644 --- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/alert_flyout.ts @@ -70,7 +70,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('anomaly detection alert', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); await ml.testResources.setKibanaTimeZoneToUTC(); await ml.securityUI.loginAsMlPowerUser(); diff --git a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/index.ts b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/index.ts index ef104c74b820..7a898b63c3f2 100644 --- a/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/index.ts +++ b/x-pack/test/functional_with_es_ssl/apps/discover_ml_uptime/ml/index.ts @@ -23,7 +23,7 @@ export default ({ loadTestFile, getService }: FtrProviderContext) => { // NOTE: Logout needs to happen before anything else to avoid flaky behavior await ml.securityUI.logout(); - await ml.testResources.deleteIndexPatternByTitle('ft_ecommerce'); + await ml.testResources.deleteDataViewByTitle('ft_ecommerce'); await esArchiver.unload('x-pack/test/functional/es_archives/ml/ecommerce'); await ml.securityCommon.cleanMlUsers(); await ml.securityCommon.cleanMlRoles(); diff --git a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_feature_id.ts b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_feature_id.ts index 94cbdbce7749..fcf67163b2bb 100644 --- a/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_feature_id.ts +++ b/x-pack/test/rule_registry/security_and_spaces/tests/basic/get_browser_fields_by_feature_id.ts @@ -45,9 +45,14 @@ export default ({ getService }: FtrProviderContext) => { 'logs', 'uptime', ]); - expect(Object.keys(resp.browserFields)).toEqual( - expect.arrayContaining(['base', 'event', 'kibana']) - ); + expect(Object.keys(resp.browserFields)).toEqual([ + 'base', + 'cloud', + 'container', + 'host', + 'kibana', + 'orchestrator', + ]); }); it(`${superUser.username} should be able to get browser fields for o11y featureIds`, async () => { @@ -57,21 +62,14 @@ export default ({ getService }: FtrProviderContext) => { 'logs', 'uptime', ]); - expect(Object.keys(resp.browserFields)).toEqual( - expect.arrayContaining([ - 'base', - 'agent', - 'anomaly', - 'ecs', - 'error', - 'event', - 'kibana', - 'monitor', - 'observer', - 'tls', - 'url', - ]) - ); + expect(Object.keys(resp.browserFields)).toEqual([ + 'base', + 'cloud', + 'container', + 'host', + 'kibana', + 'orchestrator', + ]); }); it(`${superUser.username} should NOT be able to get browser fields for siem featureId`, async () => { diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/generate_anomaly_alerts.ts b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/generate_anomaly_alerts.ts index cec6ed8528a1..8d93f1349cae 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/generate_anomaly_alerts.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/generate_anomaly_alerts.ts @@ -78,7 +78,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { describe('anomaly detection alert', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); - await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); + await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); const { job, datafeed } = createTestJobAndDatafeed(); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/geographic_data.ts b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/geographic_data.ts index e79539d01bbb..c6db2071f235 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/geographic_data.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/geographic_data.ts @@ -101,7 +101,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await ml.testExecution.logTestStep('open index in data visualizer'); await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataVisualizer(); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(LOGS_INDEX_PATTERN); await ml.testExecution.logTestStep('set data visualizer options'); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/mapping_anomalies.ts b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/mapping_anomalies.ts index c6affe8bf3c3..7dcc26758ed4 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/mapping_anomalies.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/mapping_anomalies.ts @@ -60,7 +60,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await ml.testExecution.logTestStep('open index in data visualizer'); await ml.navigation.navigateToMl(); await ml.navigation.navigateToDataVisualizer(); - await ml.dataVisualizer.navigateToIndexPatternSelection(); + await ml.dataVisualizer.navigateToDataViewSelection(); await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(LOGS_INDEX_PATTERN); await ml.testExecution.logTestStep('set data visualizer options'); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/classification.ts b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/classification.ts index 3dc766e428b5..f49750a993d0 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/classification.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/classification.ts @@ -40,12 +40,12 @@ export default function ({ getService }: FtrProviderContext) { describe('classification job', function () { before(async () => { await ml.api.createAndRunDFAJob(classificationJobConfig as DataFrameAnalyticsConfig); - await ml.testResources.createIndexPatternIfNeeded(classificationJobConfig.dest!.index!); + await ml.testResources.createDataViewIfNeeded(classificationJobConfig.dest!.index!); }); after(async () => { await ml.api.deleteDataFrameAnalyticsJobES(classificationJobConfig.id as string); - await ml.testResources.deleteIndexPatternByTitle(classificationJobConfig.dest!.index!); + await ml.testResources.deleteDataViewByTitle(classificationJobConfig.dest!.index!); await ml.api.deleteIndices(classificationJobConfig.dest!.index!); await ml.api.cleanMlIndices(); }); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/outlier_detection.ts b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/outlier_detection.ts index 73e3a22d28c9..88e6091cd008 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/outlier_detection.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/outlier_detection.ts @@ -49,19 +49,19 @@ export default function ({ getService }: FtrProviderContext) { describe('outlier detection job', function () { before(async () => { await transform.api.createAndRunTransform(transformConfig.id, transformConfig); - await ml.testResources.createIndexPatternIfNeeded(transformConfig.dest.index); + await ml.testResources.createDataViewIfNeeded(transformConfig.dest.index); await ml.api.createAndRunDFAJob(outlierJobConfig as DataFrameAnalyticsConfig); - await ml.testResources.createIndexPatternIfNeeded(outlierJobConfig.dest!.index!); + await ml.testResources.createDataViewIfNeeded(outlierJobConfig.dest!.index!); }); after(async () => { - await ml.testResources.deleteIndexPatternByTitle(transformConfig.dest.index); + await ml.testResources.deleteDataViewByTitle(transformConfig.dest.index); await transform.api.deleteIndices(transformConfig.dest.index); await transform.api.cleanTransformIndices(); await ml.api.deleteDataFrameAnalyticsJobES(outlierJobConfig.id as string); - await ml.testResources.deleteIndexPatternByTitle(outlierJobConfig.dest!.index!); + await ml.testResources.deleteDataViewByTitle(outlierJobConfig.dest!.index!); await ml.api.deleteIndices(outlierJobConfig.dest!.index!); await ml.api.cleanMlIndices(); }); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/regression.ts b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/regression.ts index edf8c8d971a6..3dc79e031a8b 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/regression.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/data_frame_analytics/regression.ts @@ -41,12 +41,12 @@ export default function ({ getService }: FtrProviderContext) { describe('regression job', function () { before(async () => { await ml.api.createAndRunDFAJob(regressionJobConfig as DataFrameAnalyticsConfig); - await ml.testResources.createIndexPatternIfNeeded(regressionJobConfig.dest!.index!); + await ml.testResources.createDataViewIfNeeded(regressionJobConfig.dest!.index!); }); after(async () => { await ml.api.deleteDataFrameAnalyticsJobES(regressionJobConfig.id as string); - await ml.testResources.deleteIndexPatternByTitle(regressionJobConfig.dest!.index!); + await ml.testResources.deleteDataViewByTitle(regressionJobConfig.dest!.index!); await ml.api.deleteIndices(regressionJobConfig.dest!.index!); await ml.api.cleanMlIndices(); }); diff --git a/x-pack/plugins/observability/common/custom_threshold_rule/constants.ts b/x-pack/test/security_solution_api_integration/config/ess/config.base.basic.ts similarity index 60% rename from x-pack/plugins/observability/common/custom_threshold_rule/constants.ts rename to x-pack/test/security_solution_api_integration/config/ess/config.base.basic.ts index 7f7c3a5bcbb3..15104fe97292 100644 --- a/x-pack/plugins/observability/common/custom_threshold_rule/constants.ts +++ b/x-pack/test/security_solution_api_integration/config/ess/config.base.basic.ts @@ -5,13 +5,9 @@ * 2.0. */ -export const METRIC_EXPLORER_AGGREGATIONS = [ - 'avg', - 'max', - 'min', - 'cardinality', - 'count', - 'sum', -] as const; +import { createTestConfig } from './config.base'; -export const CUSTOM_AGGREGATOR = 'custom'; +export default createTestConfig({ + license: 'basic', + ssl: true, +}); diff --git a/x-pack/test/security_solution_api_integration/config/serverless/config.base.essentials.ts b/x-pack/test/security_solution_api_integration/config/serverless/config.base.essentials.ts new file mode 100644 index 000000000000..377d970d3451 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/config/serverless/config.base.essentials.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { FtrConfigProviderContext } from '@kbn/test'; +export interface CreateTestConfigOptions { + testFiles: string[]; + junit: { reportName: string }; + kbnTestServerArgs?: string[]; + kbnTestServerEnv?: Record; +} +import { services } from '../../../../test_serverless/api_integration/services'; + +export function createTestConfig(options: CreateTestConfigOptions) { + return async ({ readConfigFile }: FtrConfigProviderContext) => { + const svlSharedConfig = await readConfigFile( + require.resolve('../../../../test_serverless/shared/config.base.ts') + ); + return { + ...svlSharedConfig.getAll(), + services: { + ...services, + }, + kbnTestServer: { + ...svlSharedConfig.get('kbnTestServer'), + serverArgs: [ + ...svlSharedConfig.get('kbnTestServer.serverArgs'), + '--serverless=security', + `--xpack.securitySolutionServerless.productTypes=${JSON.stringify([ + { product_line: 'security', product_tier: 'essentials' }, + { product_line: 'endpoint', product_tier: 'essentials' }, + ])}`, + ...(options.kbnTestServerArgs || []), + ], + env: { + ...svlSharedConfig.get('kbnTestServer.env'), + ...options.kbnTestServerEnv, + }, + }, + testFiles: options.testFiles, + junit: options.junit, + + mochaOpts: { + ...svlSharedConfig.get('mochaOpts'), + grep: '/^(?!.*@brokenInServerless).*@serverless.*/', + }, + }; + }; +} diff --git a/x-pack/test/security_solution_api_integration/package.json b/x-pack/test/security_solution_api_integration/package.json index 50dc47f95b1b..96d592a5c9f7 100644 --- a/x-pack/test/security_solution_api_integration/package.json +++ b/x-pack/test/security_solution_api_integration/package.json @@ -7,6 +7,8 @@ "scripts": { "initialize-server:dr:default": "node ./scripts/index.js server detections_response default_license", "run-tests:dr:default": "node ./scripts/index.js runner detections_response default_license", + "initialize-server:dr:basicEssentials": "node ./scripts/index.js server detections_response basic_essentials_license", + "run-tests:dr:basicEssentials": "node ./scripts/index.js runner detections_response basic_essentials_license", "initialize-server:ea:default": "node ./scripts/index.js server entity_analytics default_license", "run-tests:ea:default": "node ./scripts/index.js runner entity_analytics default_license", "exception_workflows:server:serverless": "npm run initialize-server:dr:default exceptions/workflows serverless", @@ -98,6 +100,11 @@ "telemetry:runner:serverless": "npm run run-tests:dr:default telemetry serverless serverlessEnv", "telemetry:qa:serverless": "npm run run-tests:dr:default telemetry serverless qaEnv", "telemetry:server:ess": "npm run initialize-server:dr:default telemetry ess", - "telemetry:runner:ess": "npm run run-tests:dr:default telemetry ess essEnv" + "telemetry:runner:ess": "npm run run-tests:dr:default telemetry ess essEnv", + "detection_engine_basicessentionals:server:serverless": "npm run initialize-server:dr:basicEssentials detection_engine serverless", + "detection_engine_basicessentionals:runner:serverless": "npm run run-tests:dr:basicEssentials detection_engine serverless serverlessEnv", + "detection_engine_basicessentionals:qa:serverless": "npm run run-tests:dr:basicEssentials detection_engine serverless qaEnv", + "detection_engine_basicessentionals:server:ess": "npm run initialize-server:dr:basicEssentials detection_engine ess", + "detection_engine_basicessentionals:runner:ess": "npm run run-tests:dr:basicEssentials detection_engine ess essEnv" } } diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/open_close_alerts.ts similarity index 52% rename from x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/open_close_alerts.ts index cc1216e80dd8..4af66d1da4a9 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/open_close_signals.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/open_close_alerts.ts @@ -14,40 +14,45 @@ import { DETECTION_ENGINE_QUERY_SIGNALS_URL, } from '@kbn/security-solution-plugin/common/constants'; import { DetectionAlert } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; import { - createSignalsIndex, - setSignalStatus, - getQuerySignalIds, + createAlertsIndex, + setAlertStatus, + getQueryAlertIds, deleteAllRules, createRule, - waitForSignalsToBePresent, - getSignalsByIds, + waitForAlertsToBePresent, + getAlertsByIds, waitForRuleSuccess, - getRuleForSignalTesting, + getRuleForAlertTesting, deleteAllAlerts, -} from '../../utils'; +} from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; +import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); const log = getService('log'); const es = getService('es'); + // TODO: add a new service + const config = getService('config'); + const isServerless = config.get('serverless'); + const dataPathBuilder = new EsArchivePathBuilder(isServerless); + const auditbeatHost = dataPathBuilder.getPath('auditbeat/hosts'); - describe('open_close_signals', () => { + describe('@ess @serverless open_close_alerts', () => { describe('tests with auditbeat data', () => { before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'); + await esArchiver.load(auditbeatHost); }); after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts'); + await esArchiver.unload(auditbeatHost); }); beforeEach(async () => { await deleteAllRules(supertest, log); - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -55,94 +60,94 @@ export default ({ getService }: FtrProviderContext) => { await deleteAllRules(supertest, log); }); - it('should be able to execute and get 10 signals', async () => { + it('should be able to execute and get 10 alerts', async () => { const rule = { - ...getRuleForSignalTesting(['auditbeat-*']), + ...getRuleForAlertTesting(['auditbeat-*']), query: 'process.executable: "/usr/bin/sudo"', }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 10, [id]); - const signalsOpen = await getSignalsByIds(supertest, log, [id]); - expect(signalsOpen.hits.hits.length).equal(10); + await waitForAlertsToBePresent(supertest, log, 10, [id]); + const alertsOpen = await getAlertsByIds(supertest, log, [id]); + expect(alertsOpen.hits.hits.length).equal(10); }); - it('should be have set the signals in an open state initially', async () => { + it('should be have set the alerts in an open state initially', async () => { const rule = { - ...getRuleForSignalTesting(['auditbeat-*']), + ...getRuleForAlertTesting(['auditbeat-*']), query: 'process.executable: "/usr/bin/sudo"', }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 10, [id]); - const signalsOpen = await getSignalsByIds(supertest, log, [id]); - const everySignalOpen = signalsOpen.hits.hits.every( + await waitForAlertsToBePresent(supertest, log, 10, [id]); + const alertsOpen = await getAlertsByIds(supertest, log, [id]); + const everyAlertOpen = alertsOpen.hits.hits.every( (hit) => hit._source?.[ALERT_WORKFLOW_STATUS] === 'open' ); - expect(everySignalOpen).to.eql(true); + expect(everyAlertOpen).to.eql(true); }); - it('should be able to get a count of 10 closed signals when closing 10', async () => { + it('should be able to get a count of 10 closed alerts when closing 10', async () => { const rule = { - ...getRuleForSignalTesting(['auditbeat-*']), + ...getRuleForAlertTesting(['auditbeat-*']), query: 'process.executable: "/usr/bin/sudo"', }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 10, [id]); - const signalsOpen = await getSignalsByIds(supertest, log, [id]); - const signalIds = signalsOpen.hits.hits.map((signal) => signal._id); + await waitForAlertsToBePresent(supertest, log, 10, [id]); + const alertsOpen = await getAlertsByIds(supertest, log, [id]); + const alertIds = alertsOpen.hits.hits.map((alert) => alert._id); - // set all of the signals to the state of closed. There is no reason to use a waitUntil here + // set all of the alerts to the state of closed. There is no reason to use a waitUntil here // as this route intentionally has a waitFor within it and should only return when the query has // the data. await supertest .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds, status: 'closed' })) + .send(setAlertStatus({ alertIds, status: 'closed' })) .expect(200); - const { body: signalsClosed }: { body: estypes.SearchResponse } = + const { body: alertsClosed }: { body: estypes.SearchResponse } = await supertest .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) .set('kbn-xsrf', 'true') - .send(getQuerySignalIds(signalIds)) + .send(getQueryAlertIds(alertIds)) .expect(200); - expect(signalsClosed.hits.hits.length).to.equal(10); + expect(alertsClosed.hits.hits.length).to.equal(10); }); // Test is failing after changing refresh to false - it.skip('should be able close 10 signals immediately and they all should be closed', async () => { + it.skip('should be able close 10 alerts immediately and they all should be closed', async () => { const rule = { - ...getRuleForSignalTesting(['auditbeat-*']), + ...getRuleForAlertTesting(['auditbeat-*']), query: 'process.executable: "/usr/bin/sudo"', }; const { id } = await createRule(supertest, log, rule); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 10, [id]); - const signalsOpen = await getSignalsByIds(supertest, log, [id]); - const signalIds = signalsOpen.hits.hits.map((signal) => signal._id); + await waitForAlertsToBePresent(supertest, log, 10, [id]); + const alertsOpen = await getAlertsByIds(supertest, log, [id]); + const alertIds = alertsOpen.hits.hits.map((alert) => alert._id); - // set all of the signals to the state of closed. There is no reason to use a waitUntil here + // set all of the alerts to the state of closed. There is no reason to use a waitUntil here // as this route intentionally has a waitFor within it and should only return when the query has // the data. await supertest .post(DETECTION_ENGINE_SIGNALS_STATUS_URL) .set('kbn-xsrf', 'true') - .send(setSignalStatus({ signalIds, status: 'closed' })) + .send(setAlertStatus({ alertIds, status: 'closed' })) .expect(200); - const { body: signalsClosed }: { body: estypes.SearchResponse } = + const { body: alertsClosed }: { body: estypes.SearchResponse } = await supertest .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) .set('kbn-xsrf', 'true') - .send(getQuerySignalIds(signalIds)) + .send(getQueryAlertIds(alertIds)) .expect(200); - const everySignalClosed = signalsClosed.hits.hits.every( + const everyAlertClosed = alertsClosed.hits.hits.every( (hit) => hit._source?.[ALERT_WORKFLOW_STATUS] === 'closed' ); - expect(everySignalClosed).to.eql(true); + expect(everyAlertClosed).to.eql(true); }); }); }); diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/query_signals.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts.ts similarity index 68% rename from x-pack/test/detection_engine_api_integration/basic/tests/query_signals.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts.ts index 2acd4ffab10b..3b372597cffd 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/query_signals.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts.ts @@ -11,25 +11,25 @@ import { DETECTION_ENGINE_QUERY_SIGNALS_URL, ALERTS_AS_DATA_FIND_URL, } from '@kbn/security-solution-plugin/common/constants'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; -import { getSignalStatus, createSignalsIndex, deleteAllAlerts } from '../../utils'; +import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common'; +import { getAlertStatus, createAlertsIndex, deleteAllAlerts } from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const supertest = getService('supertest'); const esArchiver = getService('esArchiver'); const log = getService('log'); const es = getService('es'); - describe('query_signals_route and find_alerts_route', () => { + describe('@ess @serverless query_signals_route and find_alerts_route', () => { describe('validation checks', () => { // This fails and should be investigated or removed if it no longer applies - it.skip('should not give errors when querying and the signals index does exist and is empty', async () => { - await createSignalsIndex(supertest, log); + it.skip('should not give errors when querying and the alerts index does exist and is empty', async () => { + await createAlertsIndex(supertest, log); const { body } = await supertest .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) .set('kbn-xsrf', 'true') - .send(getSignalStatus()) + .send(getAlertStatus()) .expect(200); // remove any server generated items that are indeterministic @@ -48,56 +48,19 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe('backwards compatibility', () => { - before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/endpoint/resolver/signals'); - await createSignalsIndex(supertest, log); - }); - after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/endpoint/resolver/signals'); - await deleteAllAlerts(supertest, log, es); - }); - - it('should be able to filter old signals on host.os.name.caseless using runtime field', async () => { - const query = { - query: { - bool: { - should: [{ match_phrase: { 'host.os.name.caseless': 'windows' } }], - }, - }, - }; - const { body } = await supertest - .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) - .set('kbn-xsrf', 'true') - .send(query) - .expect(200); - expect(body.hits.total.value).to.eql(3); - }); - - it('should be able to filter old signals using field aliases', async () => { - const query = { - query: { - bool: { - should: [{ match_phrase: { 'kibana.alert.workflow_status': 'open' } }], - }, - }, - }; - const { body } = await supertest - .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) - .set('kbn-xsrf', 'true') - .send(query) - .expect(200); - expect(body.hits.total.value).to.eql(3); - }); - }); - describe('runtime fields', () => { before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/endpoint/resolver/signals'); - await createSignalsIndex(supertest, log); + await esArchiver.load( + 'x-pack/test/functional/es_archives/security_solution/alerts/8.8.0_multiple_docs', + { + useCreate: true, + docsOnly: true, + } + ); + await createAlertsIndex(supertest, log); }); after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/endpoint/resolver/signals'); + // await esArchiver.unload('x-pack/test/functional/es_archives/endpoint/resolver/signals'); await deleteAllAlerts(supertest, log, es); }); @@ -129,12 +92,12 @@ export default ({ getService }: FtrProviderContext) => { describe('find_alerts_route', () => { describe('validation checks', () => { // This fails and should be investigated or removed if it no longer applies - it.skip('should not give errors when querying and the signals index does exist and is empty', async () => { - await createSignalsIndex(supertest, log); + it.skip('should not give errors when querying and the alerts index does exist and is empty', async () => { + await createAlertsIndex(supertest, log); const { body } = await supertest .post(ALERTS_AS_DATA_FIND_URL) .set('kbn-xsrf', 'true') - .send({ ...getSignalStatus(), index: '.siem-signals-default' }) + .send({ ...getAlertStatus(), index: '.siem-signals-default' }) .expect(200); // remove any server generated items that are indeterministic @@ -153,10 +116,11 @@ export default ({ getService }: FtrProviderContext) => { }); it('should not give errors when executing security solution histogram aggs', async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); await supertest .post(ALERTS_AS_DATA_FIND_URL) .set('kbn-xsrf', 'true') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .send({ index: '.siem-signals-default', aggs: { diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts_backword_compatibility.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts_backword_compatibility.ts new file mode 100644 index 000000000000..76f85dd32397 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/alerts/query_alerts_backword_compatibility.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { DETECTION_ENGINE_QUERY_SIGNALS_URL } from '@kbn/security-solution-plugin/common/constants'; +import { createAlertsIndex, deleteAllAlerts } from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + const log = getService('log'); + const es = getService('es'); + + describe('@ess query_alerts_backword_compatibility', () => { + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/endpoint/resolver/signals'); + await createAlertsIndex(supertest, log); + }); + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/endpoint/resolver/signals'); + await deleteAllAlerts(supertest, log, es); + }); + + it('should be able to filter old alerts on host.os.name.caseless using runtime field', async () => { + const query = { + query: { + bool: { + should: [{ match_phrase: { 'host.os.name.caseless': 'windows' } }], + }, + }, + }; + const { body } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send(query) + .expect(200); + expect(body.hits.total.value).to.eql(3); + }); + + it('should be able to filter old alerts using field aliases', async () => { + const query = { + query: { + bool: { + should: [{ match_phrase: { 'kibana.alert.workflow_status': 'open' } }], + }, + }, + }; + const { body } = await supertest + .post(DETECTION_ENGINE_QUERY_SIGNALS_URL) + .set('kbn-xsrf', 'true') + .send(query) + .expect(200); + expect(body.hits.total.value).to.eql(3); + }); + }); +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/ess.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/ess.config.ts new file mode 100644 index 000000000000..b980aef5f783 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/ess.config.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 { FtrConfigProviderContext } from '@kbn/test'; + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile( + require.resolve('../../../../../config/ess/config.base.basic') + ); + + return { + ...functionalConfig.getAll(), + testFiles: [require.resolve('..')], + junit: { + reportName: 'Detection Engine ESS - Basic Integration Tests', + }, + }; +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/serverless.config.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/serverless.config.ts new file mode 100644 index 000000000000..8a4199ccfb44 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/configs/serverless.config.ts @@ -0,0 +1,15 @@ +/* + * 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 { createTestConfig } from '../../../../../config/serverless/config.base.essentials'; + +export default createTestConfig({ + testFiles: [require.resolve('..')], + junit: { + reportName: 'Detection Engine Serverless - Essentials Integration Tests', + }, +}); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/index.ts new file mode 100644 index 000000000000..296cec0e0644 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Detection Engine Basic and Essentials API', function () { + loadTestFile(require.resolve('./rules/create_rules')); + loadTestFile(require.resolve('./rules/create_ml_rules_privileges')); + loadTestFile(require.resolve('./alerts/open_close_alerts')); + loadTestFile(require.resolve('./alerts/query_alerts')); + loadTestFile(require.resolve('./alerts/query_alerts_backword_compatibility')); + }); +} diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_ml_rules_privileges.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_ml_rules_privileges.ts new file mode 100644 index 000000000000..0b4bcea421c7 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_ml_rules_privileges.ts @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from 'expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; + +import { + createAlertsIndex, + deleteAllRules, + removeServerGeneratedProperties, + getSimpleMlRule, + deleteAllAlerts, + updateUsername, +} from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; +import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder'; + +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertest'); + const log = getService('log'); + const es = getService('es'); + // TODO: add a new service + const config = getService('config'); + const ELASTICSEARCH_USERNAME = config.get('servers.kibana.username'); + const isServerless = config.get('serverless'); + const dataPathBuilder = new EsArchivePathBuilder(isServerless); + const auditbeatPath = dataPathBuilder.getPath('auditbeat/hosts'); + + describe('create_ml_rules', () => { + describe('Creating Machine Learning rules', () => { + before(async () => { + await esArchiver.load(auditbeatPath); + }); + + after(async () => { + await esArchiver.unload(auditbeatPath); + }); + + beforeEach(async () => { + await createAlertsIndex(supertest, log); + }); + + afterEach(async () => { + await deleteAllAlerts(supertest, log, es); + await deleteAllRules(supertest, log); + }); + + it('@ess should give a 403 when trying to create a single Machine Learning rule since the license is basic', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_URL) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .send(getSimpleMlRule()) + .expect(403); + + const bodyToCompare = removeServerGeneratedProperties(body); + expect(bodyToCompare).toEqual({ + message: 'Your license does not support machine learning. Please upgrade your license.', + status_code: 403, + }); + }); + it('@serverless should give a 200 when trying to create a single Machine Learning rule since the license is essentials', async () => { + const { body } = await supertest + .post(DETECTION_ENGINE_RULES_URL) + .set('kbn-xsrf', 'true') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') + .send(getSimpleMlRule()) + .expect(200); + + const bodyToCompare = removeServerGeneratedProperties(body); + const expectedRule = updateUsername(getSimpleMlRule(), ELASTICSEARCH_USERNAME); + expect(bodyToCompare).toEqual(expect.objectContaining(expectedRule)); + }); + }); + }); +}; diff --git a/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_rules.ts similarity index 55% rename from x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_rules.ts index fbbef2098464..6a3fff87611d 100644 --- a/x-pack/test/detection_engine_api_integration/basic/tests/create_rules.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/basic_essentials_license/detection_engine/rules/create_rules.ts @@ -6,42 +6,49 @@ */ import expect from '@kbn/expect'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { RuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; + import { - createSignalsIndex, + createAlertsIndex, deleteAllRules, getSimpleRule, - getSimpleRuleOutput, getSimpleRuleOutputWithoutRuleId, getSimpleRuleWithoutRuleId, removeServerGeneratedProperties, removeServerGeneratedPropertiesIncludingRuleId, - getSimpleMlRule, deleteAllAlerts, -} from '../../utils'; + updateUsername, +} from '../../../utils'; +import { FtrProviderContext } from '../../../../../ftr_provider_context'; +import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder'; -// eslint-disable-next-line import/no-default-export export default ({ getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const supertest = getService('supertest'); const log = getService('log'); const es = getService('es'); - - describe('create_rules', () => { + // TODO: add a new service + const config = getService('config'); + const ELASTICSEARCH_USERNAME = config.get('servers.kibana.username'); + const isServerless = config.get('serverless'); + const dataPathBuilder = new EsArchivePathBuilder(isServerless); + const auditbeatPath = dataPathBuilder.getPath('auditbeat/hosts'); + + describe('@ess @serverless create_rules', () => { describe('creating rules', () => { before(async () => { - await esArchiver.load('x-pack/test/functional/es_archives/auditbeat/hosts'); + await esArchiver.load(auditbeatPath); }); after(async () => { - await esArchiver.unload('x-pack/test/functional/es_archives/auditbeat/hosts'); + await esArchiver.unload(auditbeatPath); }); beforeEach(async () => { - await createSignalsIndex(supertest, log); + await createAlertsIndex(supertest, log); }); afterEach(async () => { @@ -53,12 +60,14 @@ export default ({ getService }: FtrProviderContext) => { const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .send(getSimpleRule()) .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - expect(bodyToCompare).to.eql(getSimpleRuleOutput()); + const expectedRule = updateUsername(bodyToCompare, ELASTICSEARCH_USERNAME); + + expect(bodyToCompare).to.eql(expectedRule); }); it('should create a single rule without an input index', async () => { @@ -72,90 +81,49 @@ export default ({ getService }: FtrProviderContext) => { type: 'query', query: 'user.name: root or user.name: admin', }; - const expected = { - actions: [], - author: [], - created_by: 'elastic', - description: 'Simple Rule Query', - enabled: true, - false_positives: [], - from: 'now-6m', - immutable: false, - interval: '5m', - rule_id: 'rule-1', - language: 'kuery', - output_index: '', - max_signals: 100, - risk_score: 1, - risk_score_mapping: [], - name: 'Simple Rule Query', - query: 'user.name: root or user.name: admin', - references: [], - related_integrations: [], - required_fields: [], - setup: '', - severity: 'high', - severity_mapping: [], - updated_by: 'elastic', - tags: [], - to: 'now', - type: 'query', - threat: [], - exceptions_list: [], - version: 1, - revision: 0, - }; const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .send(rule) .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); - expect(bodyToCompare).to.eql(expected); + const expectedRule = updateUsername(bodyToCompare, ELASTICSEARCH_USERNAME); + + expect(bodyToCompare).to.eql(expectedRule); }); it('should create a single rule without a rule_id', async () => { const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .send(getSimpleRuleWithoutRuleId()) .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body); - expect(bodyToCompare).to.eql(getSimpleRuleOutputWithoutRuleId()); - }); - - it('should give a 403 when trying to create a single Machine Learning rule since the license is basic', async () => { - const { body } = await supertest - .post(DETECTION_ENGINE_RULES_URL) - .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') - .send(getSimpleMlRule()) - .expect(403); + const expectedRule = updateUsername( + getSimpleRuleOutputWithoutRuleId(), + ELASTICSEARCH_USERNAME + ); - const bodyToCompare = removeServerGeneratedProperties(body); - expect(bodyToCompare).to.eql({ - message: 'Your license does not support machine learning. Please upgrade your license.', - status_code: 403, - }); + expect(bodyToCompare).to.eql(expectedRule); }); it('should cause a 409 conflict if we attempt to create the same rule_id twice', async () => { await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .send(getSimpleRule()) .expect(200); const { body } = await supertest .post(DETECTION_ENGINE_RULES_URL) .set('kbn-xsrf', 'true') - .set('elastic-api-version', '2023-10-31') + .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31') .send(getSimpleRule()) .expect(409); diff --git a/x-pack/test/detection_engine_api_integration/utils/get_signal_status.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/get_alert_status.ts similarity index 89% rename from x-pack/test/detection_engine_api_integration/utils/get_signal_status.ts rename to x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/get_alert_status.ts index d3c922c30ccc..212aefd4593f 100644 --- a/x-pack/test/detection_engine_api_integration/utils/get_signal_status.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/get_alert_status.ts @@ -5,6 +5,6 @@ * 2.0. */ -export const getSignalStatus = () => ({ +export const getAlertStatus = () => ({ aggs: { statuses: { terms: { field: 'kibana.alert.workflow_status', size: 10 } } }, }); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/index.ts index 975c6ffa509c..e78bfa1922d3 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/alerts/index.ts @@ -20,4 +20,5 @@ export * from './get_alert_status_empty_response'; export * from './get_query_alert_ids'; export * from './set_alert_tags'; export * from './get_preview_alerts'; +export * from './get_alert_status'; export * from './migrations'; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_output_without_rule_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_output_without_rule_id.ts new file mode 100644 index 000000000000..56b5ab66773b --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_output_without_rule_id.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 { getSimpleRuleOutput } from './get_simple_rule_output'; +import { RuleWithoutServerGeneratedProperties } from './remove_server_generated_properties'; + +/** + * This is the typical output of a simple rule that Kibana will output with all the defaults except + * for all the server generated properties such as created_by. Useful for testing end to end tests. + */ +export const getSimpleRuleOutputWithoutRuleId = ( + ruleId = 'rule-1' +): Omit => { + const rule = getSimpleRuleOutput(ruleId); + const { rule_id: rId, ...ruleWithoutRuleId } = rule; + return ruleWithoutRuleId; +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_without_rule_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_without_rule_id.ts new file mode 100644 index 000000000000..ad6ab7803ec2 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/get_simple_rule_without_rule_id.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { RuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine'; +import { getSimpleRule } from './get_simple_rule'; + +/** + * This is a typical simple rule for testing that is easy for most basic testing + */ +export const getSimpleRuleWithoutRuleId = (): RuleCreateProps => { + const simpleRule = getSimpleRule(); + // eslint-disable-next-line @typescript-eslint/naming-convention + const { rule_id, ...ruleWithoutId } = simpleRule; + return ruleWithoutId; +}; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts index db5ccb307395..04c4cb778ef4 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/index.ts @@ -39,5 +39,8 @@ export * from './generate_event'; export * from './create_legacy_rule_action'; export * from './get_simple_threat_match'; export * from './get_simple_ml_rule'; +export * from './remove_server_generated_properties_including_rule_id'; +export * from './get_simple_rule_output_without_rule_id'; +export * from './get_simple_rule_without_rule_id'; export * from './prebuilt_rules'; diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/remove_server_generated_properties_including_rule_id.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/remove_server_generated_properties_including_rule_id.ts new file mode 100644 index 000000000000..1b57b5663ec2 --- /dev/null +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/utils/rules/remove_server_generated_properties_including_rule_id.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 { RuleResponse } from '@kbn/security-solution-plugin/common/api/detection_engine'; + +import { removeServerGeneratedProperties } from './remove_server_generated_properties'; + +/** + * This will remove server generated properties such as date times, etc... including the rule_id + * @param rule Rule to pass in to remove typical server generated properties + */ +export const removeServerGeneratedPropertiesIncludingRuleId = ( + rule: RuleResponse +): Partial => { + const ruleWithRemovedProperties = removeServerGeneratedProperties(rule); + // eslint-disable-next-line @typescript-eslint/naming-convention + const { rule_id, ...additionalRuledIdRemoved } = ruleWithRemovedProperties; + return additionalRuledIdRemoved; +}; diff --git a/x-pack/test/security_solution_cypress/config.ts b/x-pack/test/security_solution_cypress/config.ts index 99390aa5142a..fb34362f7fb9 100644 --- a/x-pack/test/security_solution_cypress/config.ts +++ b/x-pack/test/security_solution_cypress/config.ts @@ -46,7 +46,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { '--xpack.ruleRegistry.unsafe.legacyMultiTenancy.enabled=true', `--xpack.securitySolution.enableExperimental=${JSON.stringify([ 'chartEmbeddablesEnabled', - 'disableTimelineSaveTour', ])}`, // mock cloud to enable the guided onboarding tour in e2e tests '--xpack.cloud.id=test', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts index e7f17ddcc8cb..927e1f58a1be 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts @@ -30,7 +30,7 @@ import { openFirstAlert, } from '../../../tasks/alerts'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_tags.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_tags.cy.ts index 162c63ad3ce4..4fb4d50e7c6d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_tags.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_tags.cy.ts @@ -13,7 +13,7 @@ import { updateAlertTags, } from '../../../tasks/alerts'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visitWithTimeRange } from '../../../tasks/navigation'; import { ALERTS_URL } from '../../../urls/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_via_fleet.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_via_fleet.cy.ts index 630bd099a1d0..6da3d58c0530 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_via_fleet.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_via_fleet.cy.ts @@ -8,12 +8,13 @@ import type { BulkInstallPackageInfo } from '@kbn/fleet-plugin/common'; import type { Rule } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types'; -import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common'; +import { resetRulesTableState } from '../../../tasks/common'; import { INSTALL_ALL_RULES_BUTTON, TOASTER } from '../../../screens/alerts_detection_rules'; import { getRuleAssets } from '../../../tasks/api_calls/prebuilt_rules'; import { login } from '../../../tasks/login'; import { clickAddElasticRulesButton } from '../../../tasks/prebuilt_rules'; import { visitRulesManagementTable } from '../../../tasks/rules_management'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; describe( 'Detection rules, Prebuilt Rules Installation and Update workflow', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_workflow.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_workflow.cy.ts index 15e77fad28d0..ec4615bcf59e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_workflow.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/install_workflow.cy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common'; +import { resetRulesTableState } from '../../../tasks/common'; import { createRuleAssetSavedObject } from '../../../helpers/rules'; import { getInstallSingleRuleButtonByRuleId, @@ -28,6 +28,7 @@ import { clickAddElasticRulesButton, } from '../../../tasks/prebuilt_rules'; import { visitRulesManagementTable } from '../../../tasks/rules_management'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; describe( 'Detection rules, Prebuilt Rules Installation and Update workflow', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/management.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/management.cy.ts index d5a3f3bb8532..f3101f513915 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/management.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/management.cy.ts @@ -35,7 +35,7 @@ import { getAvailablePrebuiltRulesCount, preventPrebuiltRulesPackageInstallation, } from '../../../tasks/api_calls/prebuilt_rules'; -import { deleteAlertsAndRules, deletePrebuiltRulesAssets } from '../../../tasks/common'; +import { deleteAlertsAndRules, deletePrebuiltRulesAssets } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/notifications.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/notifications.cy.ts index 180c435c1021..92bf9e7f1471 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/notifications.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/notifications.cy.ts @@ -12,16 +12,13 @@ import { RULES_UPDATES_TAB, } from '../../../screens/alerts_detection_rules'; import { deleteFirstRule } from '../../../tasks/alerts_detection_rules'; +import { deleteAlertsAndRules, deletePrebuiltRulesAssets } from '../../../tasks/api_calls/common'; import { installAllPrebuiltRulesRequest, installPrebuiltRuleAssets, createAndInstallMockedPrebuiltRules, } from '../../../tasks/api_calls/prebuilt_rules'; -import { - resetRulesTableState, - deleteAlertsAndRules, - deletePrebuiltRulesAssets, -} from '../../../tasks/common'; +import { resetRulesTableState } from '../../../tasks/common'; import { login } from '../../../tasks/login'; import { visitRulesManagementTable } from '../../../tasks/rules_management'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_preview.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_preview.cy.ts index 0b49fe4bb1de..6deeb6f5202c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_preview.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/prebuilt_rules_preview.cy.ts @@ -26,12 +26,7 @@ import { } from '../../../tasks/api_calls/prebuilt_rules'; import { createSavedQuery, deleteSavedQueries } from '../../../tasks/api_calls/saved_queries'; import { fetchMachineLearningModules } from '../../../tasks/api_calls/machine_learning'; -import { - resetRulesTableState, - deleteAlertsAndRules, - postDataView, - deleteDataView, -} from '../../../tasks/common'; +import { resetRulesTableState } from '../../../tasks/common'; import { login } from '../../../tasks/login'; import { assertRuleInstallationSuccessToastShown, @@ -62,6 +57,11 @@ import { openRuleUpdatePreview, } from '../../../tasks/prebuilt_rules_preview'; import { visitRulesManagementTable } from '../../../tasks/rules_management'; +import { + deleteAlertsAndRules, + deleteDataView, + postDataView, +} from '../../../tasks/api_calls/common'; const TEST_ENV_TAGS = ['@ess', '@serverless']; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/update_workflow.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/update_workflow.ts index 2e38b4782b43..edeb8ac98623 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/update_workflow.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/prebuilt_rules/update_workflow.ts @@ -15,11 +15,12 @@ import { UPGRADE_SELECTED_RULES_BUTTON, } from '../../../screens/alerts_detection_rules'; import { selectRulesByName } from '../../../tasks/alerts_detection_rules'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { installPrebuiltRuleAssets, createAndInstallMockedPrebuiltRules, } from '../../../tasks/api_calls/prebuilt_rules'; -import { resetRulesTableState, deleteAlertsAndRules } from '../../../tasks/common'; +import { resetRulesTableState } from '../../../tasks/common'; import { login } from '../../../tasks/login'; import { assertRulesNotPresentInRuleUpdatesTable, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts index 98080cb3b47e..3053f8e5c569 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions.cy.ts @@ -10,7 +10,11 @@ import { getSimpleCustomQueryRule } from '../../../objects/rule'; import { goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; import { deleteIndex, waitForNewDocumentToBeIndexed } from '../../../tasks/api_calls/elasticsearch'; -import { deleteAlertsAndRules, deleteConnectors, deleteDataView } from '../../../tasks/common'; +import { + deleteAlertsAndRules, + deleteConnectors, + deleteDataView, +} from '../../../tasks/api_calls/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_complete.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_complete.cy.ts index 23421b218bcb..13c35a3cce6c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_complete.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_complete.cy.ts @@ -18,7 +18,7 @@ import { import { createRule } from '../../../tasks/api_calls/rules'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { goToActionsStepTab } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_essentials.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_essentials.cy.ts index 83503ea98738..d36cdc7137de 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_essentials.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_actions/rule_actions_pli_essentials.cy.ts @@ -18,7 +18,7 @@ import { import { createRule } from '../../../tasks/api_calls/rules'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { goToActionsStepTab } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts index e8780d8696d2..9628f03f2d10 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/common_flows.cy.ts @@ -19,7 +19,7 @@ import { } from '../../../screens/create_new_rule'; import { RULE_NAME_HEADER } from '../../../screens/rule_details'; import { createTimeline } from '../../../tasks/api_calls/timelines'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { createAndEnableRule, expandAdvancedSettings, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts index e4bb4b2bfba8..5e41440f48f4 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule.cy.ts @@ -8,7 +8,7 @@ import { getNewRule } from '../../../objects/rule'; import { RULE_NAME_HEADER } from '../../../screens/rule_details'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { fillScheduleRuleAndContinue, fillAboutRuleMinimumAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts index d13a676e8425..7a6d1fa889e5 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_query_rule_data_view.cy.ts @@ -52,7 +52,11 @@ import { getRulesManagementTableRows, goToRuleDetailsOf, } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules, deleteDataView, postDataView } from '../../../tasks/common'; +import { + deleteAlertsAndRules, + deleteDataView, + postDataView, +} from '../../../tasks/api_calls/common'; import { createAndEnableRule, createRuleWithoutEnabling, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts index 03ba3db7f25f..f55a51d8e4f6 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/custom_saved_query_rule.cy.ts @@ -24,7 +24,7 @@ import { import { editFirstRule, goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; import { createSavedQuery, deleteSavedQueries } from '../../../tasks/api_calls/saved_queries'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_ess.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_ess.cy.ts index 2fa97e4f76e4..e543589bb44c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_ess.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/esql_rule_ess.cy.ts @@ -18,7 +18,7 @@ import { ESQL_TYPE, ESQL_QUERY_BAR } from '../../../screens/create_new_rule'; import { getDetails, goBackToRulesTable } from '../../../tasks/rule_details'; import { expectNumberOfRules } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { fillAboutRuleAndContinue, fillDefineEsqlRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts index b89546066185..0966ae270911 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/event_correlation_rule.cy.ts @@ -43,7 +43,7 @@ import { import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; import { expectNumberOfRules, goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts index 6dbe81076c91..2b83c938b947 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/indicator_match_rule.cy.ts @@ -111,7 +111,7 @@ import { import { CREATE_RULE_URL } from '../../../urls/navigation'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; import { openRuleManagementPageViaBreadcrumbs } from '../../../tasks/rules_management'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; const DEFAULT_THREAT_MATCH_QUERY = '@timestamp >= "now-30d/d"'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts index 8b8c6fe4e145..570f19f3f72e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/new_terms_rule.cy.ts @@ -45,7 +45,7 @@ import { import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; import { expectNumberOfRules, goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts index 585cd9187f3e..9bb9f569c4dd 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/override.cy.ts @@ -47,7 +47,7 @@ import { TIMESTAMP_OVERRIDE_DETAILS, } from '../../../screens/rule_details'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { expectNumberOfRules, goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; import { createAndEnableRule, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts index 503b40f56830..62fdb9121c9c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_creation/threshold_rule.cy.ts @@ -45,7 +45,7 @@ import { import { getDetails, waitForTheRuleToBeExecuted } from '../../../tasks/rule_details'; import { expectNumberOfRules, goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { createAndEnableRule, fillAboutRuleAndContinue, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/common_flows.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/common_flows.cy.ts index 5e5af0e6ad4a..f5704122d9e3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/common_flows.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/common_flows.cy.ts @@ -45,7 +45,7 @@ import { } from '../../../screens/rule_details'; import { createTimeline } from '../../../tasks/api_calls/timelines'; -import { deleteAlertsAndRules, deleteConnectors } from '../../../tasks/common'; +import { deleteAlertsAndRules, deleteConnectors } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; import { ruleDetailsUrl } from '../../../urls/rule_details'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/esql_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/esql_rule.cy.ts index 93100216692a..7d1419e911e3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/esql_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_details/esql_rule.cy.ts @@ -17,7 +17,7 @@ import { import { createRule } from '../../../tasks/api_calls/rules'; import { getDetails } from '../../../tasks/rule_details'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/custom_query_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/custom_query_rule.cy.ts index ca6d6c56adcf..e9497851d4cb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/custom_query_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/custom_query_rule.cy.ts @@ -42,7 +42,7 @@ import { } from '../../../screens/rule_details'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules, deleteConnectors } from '../../../tasks/common'; +import { deleteAlertsAndRules, deleteConnectors } from '../../../tasks/api_calls/common'; import { addEmailConnectorAndRuleAction } from '../../../tasks/common/rule_actions'; import { fillAboutRule, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/esql_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/esql_rule.cy.ts index eb16d89a6af8..20d48b211995 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/esql_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_edit/esql_rule.cy.ts @@ -15,7 +15,7 @@ import { createRule } from '../../../tasks/api_calls/rules'; import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; import { getDetails } from '../../../tasks/rule_details'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { clearEsqlQueryBar, fillEsqlQueryBar, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts index 1376e486790b..51aa3f406b8e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/related_integrations/related_integrations.cy.ts @@ -26,14 +26,14 @@ import { disableRelatedIntegrations, enableRelatedIntegrations, } from '../../../../tasks/api_calls/kibana_advanced_settings'; -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { login } from '../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../tasks/rules_management'; import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule'; import { installIntegrations, PackagePolicyWithoutAgentPolicyId, -} from '../../../../tasks/integrations'; +} from '../../../../tasks/api_calls/integrations'; import { disableAutoRefresh, openIntegrationsPopover, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts index fd6b28fbe57e..dd053ab958aa 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_duplicate_rules.cy.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { deleteAlertsAndRules } from '../../../../../tasks/api_calls/common'; import { goToRuleDetailsOf, expectManagementTableRules, @@ -21,7 +22,7 @@ import { login } from '../../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../../tasks/rules_management'; import { createRule } from '../../../../../tasks/api_calls/rules'; -import { resetRulesTableState, deleteAlertsAndRules } from '../../../../../tasks/common'; +import { resetRulesTableState } from '../../../../../tasks/common'; import { getNewRule } from '../../../../../objects/rule'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts index 920c03529c11..94b6804b3119 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules.cy.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { deleteAlertsAndRules } from '../../../../../tasks/api_calls/common'; import { MODAL_CONFIRMATION_BTN, MODAL_CONFIRMATION_BODY, @@ -79,7 +80,7 @@ import { login } from '../../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../../tasks/rules_management'; import { createRule } from '../../../../../tasks/api_calls/rules'; import { loadPrepackagedTimelineTemplates } from '../../../../../tasks/api_calls/timelines'; -import { resetRulesTableState, deleteAlertsAndRules } from '../../../../../tasks/common'; +import { resetRulesTableState } from '../../../../../tasks/common'; import { getEqlRule, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts index ac6c723dbc0c..62acef933f03 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_actions.cy.ts @@ -20,7 +20,7 @@ import { } from '../../../../../screens/rules_bulk_actions'; import { actionFormSelector } from '../../../../../screens/common/rule_actions'; -import { deleteAlertsAndRules, deleteConnectors } from '../../../../../tasks/common'; +import { deleteAlertsAndRules, deleteConnectors } from '../../../../../tasks/api_calls/common'; import type { RuleActionCustomFrequency } from '../../../../../tasks/common/rule_actions'; import { addSlackRuleAction, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts index 21adb447d2ce..3b9ddf73ad3c 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/bulk_actions/bulk_edit_rules_data_view.cy.ts @@ -39,7 +39,11 @@ import { login } from '../../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../../tasks/rules_management'; import { createRule } from '../../../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules, deleteDataView, postDataView } from '../../../../../tasks/common'; +import { + deleteAlertsAndRules, + deleteDataView, + postDataView, +} from '../../../../../tasks/api_calls/common'; import { getEqlRule, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/deletion/rule_delete.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/deletion/rule_delete.cy.ts index 0896438e275e..4c9168744920 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/deletion/rule_delete.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/deletion/rule_delete.cy.ts @@ -18,7 +18,7 @@ import { } from '../../../../../tasks/alerts_detection_rules'; import { deleteSelectedRules } from '../../../../../tasks/rules_bulk_actions'; import { createRule, findAllRules } from '../../../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../../tasks/api_calls/common'; import { login } from '../../../../../tasks/login'; describe('Rule deletion', { tags: ['@ess', '@serverless'] }, () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts index 0fb3d6f08613..0cfcc4371449 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/export_rule.cy.ts @@ -7,6 +7,7 @@ import path from 'path'; +import { deleteAlertsAndRules } from '../../../../../tasks/api_calls/common'; import { expectedExportedRule, getNewRule } from '../../../../../objects/rule'; import { TOASTER_BODY, @@ -29,7 +30,7 @@ import { } from '../../../../../tasks/api_calls/exceptions'; import { getExceptionList } from '../../../../../objects/exception'; import { createRule } from '../../../../../tasks/api_calls/rules'; -import { resetRulesTableState, deleteAlertsAndRules } from '../../../../../tasks/common'; +import { resetRulesTableState } from '../../../../../tasks/common'; import { login } from '../../../../../tasks/login'; import { visit } from '../../../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts index 197ad5a9a82f..4b8fe5b5312b 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/import_export/import_rules.cy.ts @@ -11,7 +11,7 @@ import { importRules, importRulesWithOverwriteAll, } from '../../../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../../tasks/api_calls/common'; import { deleteExceptionList } from '../../../../../tasks/api_calls/exceptions'; import { login } from '../../../../../tasks/login'; import { visit } from '../../../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts index 025aff9510d9..7e753d42b6b6 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rule_actions/snoozing/rule_snoozing.cy.ts @@ -9,7 +9,7 @@ import { INTERNAL_ALERTING_API_FIND_RULES_PATH } from '@kbn/alerting-plugin/comm import type { RuleResponse } from '@kbn/security-solution-plugin/common/api/detection_engine'; import { createRule, snoozeRule as snoozeRuleViaAPI } from '../../../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules, deleteConnectors } from '../../../../../tasks/common'; +import { deleteAlertsAndRules, deleteConnectors } from '../../../../../tasks/api_calls/common'; import { login } from '../../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../../tasks/rules_management'; import { getNewRule } from '../../../../../objects/rule'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts index b76b862c70d0..117fc0eee632 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_filtering.cy.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { resetRulesTableState, deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; +import { resetRulesTableState } from '../../../../tasks/common'; import { login } from '../../../../tasks/login'; import { visitRulesManagementTable } from '../../../../tasks/rules_management'; import { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts index cf81271c1ad3..ace4406b1c22 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/rule_management/rules_table/rules_table_links.cy.ts @@ -8,7 +8,7 @@ import { getNewRule } from '../../../../objects/rule'; import { RULES_MONITORING_TAB, RULE_NAME } from '../../../../screens/alerts_detection_rules'; import { createRule } from '../../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { login } from '../../../../tasks/login'; import { visit } from '../../../../tasks/navigation'; import { RULES_MANAGEMENT_URL } from '../../../../urls/rules_management'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/create_runtime_field.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/create_runtime_field.cy.ts index 2fd13f8b6696..6838532d5593 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/create_runtime_field.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/create_runtime_field.cy.ts @@ -19,9 +19,9 @@ import { refreshPage } from '../../../tasks/security_header'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { createField } from '../../../tasks/create_runtime_field'; import { openAlertsFieldBrowser } from '../../../tasks/alerts'; -import { deleteRuntimeField } from '../../../tasks/sourcerer'; import { GET_DATA_GRID_HEADER } from '../../../screens/common/data_grid'; import { GET_TIMELINE_HEADER } from '../../../screens/timeline'; +import { deleteRuntimeField } from '../../../tasks/api_calls/sourcerer'; const alertRunTimeField = 'field.name.alert.page'; const timelineRuntimeField = 'field.name.timeline'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer.cy.ts index dbf5a5975f66..d27444e3d9a8 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer.cy.ts @@ -26,7 +26,7 @@ import { resetSourcerer, saveSourcerer, } from '../../../tasks/sourcerer'; -import { postDataView } from '../../../tasks/common'; +import { postDataView } from '../../../tasks/api_calls/common'; import { SOURCERER } from '../../../screens/sourcerer'; const siemDataViewTitle = 'Security Default Data View'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer_permissions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer_permissions.cy.ts index 52b8ccee8215..ce6b7e753d10 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer_permissions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/sourcerer/sourcerer_permissions.cy.ts @@ -9,7 +9,7 @@ import { loginWithUser } from '../../../tasks/login'; import { visitWithUser } from '../../../tasks/navigation'; import { hostsUrl } from '../../../urls/navigation'; -import { postDataView } from '../../../tasks/common'; +import { postDataView } from '../../../tasks/api_calls/common'; import { createUsersAndRoles, secReadCasesAll, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts index fe8d51cae795..60b93650048d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics/enrichments.cy.ts @@ -17,7 +17,7 @@ import { import { ENRICHED_DATA_ROW } from '../../screens/alerts_details'; import { createRule } from '../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../tasks/common'; +import { deleteAlertsAndRules } from '../../tasks/api_calls/common'; import { waitForAlertsToPopulate } from '../../tasks/create_new_rule'; import { expandFirstAlert, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts index 8914b0c98076..c4b605b85dcb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/endpoint_exceptions.cy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { expandFirstAlert, goToClosedAlertsOnRuleDetailsPage, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts index ee10a2e702b0..8dccaa04bdc8 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/auto_populate_with_alert_data.cy.ts @@ -26,7 +26,7 @@ import { import { login } from '../../../../tasks/login'; import { goToExceptionsTab, visitRuleDetailsPage } from '../../../../tasks/rule_details'; -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { ADD_AND_BTN, ENTRY_DELETE_BTN, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts index 986bcb107124..93e79ba9fa53 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/alerts_table_flow/rule_exceptions/closing_all_matching_alerts.cy.ts @@ -10,7 +10,7 @@ import { goToClosedAlertsOnRuleDetailsPage, waitForAlerts, } from '../../../../tasks/alerts'; -import { deleteAlertsAndRules, postDataView } from '../../../../tasks/common'; +import { deleteAlertsAndRules, postDataView } from '../../../../tasks/api_calls/common'; import { login } from '../../../../tasks/login'; import { visitRuleDetailsPage } from '../../../../tasks/rule_details'; import { createRule } from '../../../../tasks/api_calls/rules'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts index 3c613f32d2c7..72c18b27a9b2 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/flyout_validation.cy.ts @@ -47,7 +47,7 @@ import { FIELD_INPUT_PARENT, } from '../../../screens/exceptions'; -import { deleteAlertsAndRules, reload } from '../../../tasks/common'; +import { reload } from '../../../tasks/common'; import { createExceptionList, createExceptionListItem, @@ -55,6 +55,7 @@ import { deleteExceptionList, } from '../../../tasks/api_calls/exceptions'; import { getExceptionList } from '../../../objects/exception'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; // TODO: https://github.com/elastic/kibana/issues/161539 // Test Skipped until we fix the Flyout rerendering issue diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/match_any.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/match_any.cy.ts index f18b056c4e25..282e8d3c8122 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/match_any.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/match_any.cy.ts @@ -26,7 +26,7 @@ import { submitNewExceptionItem, } from '../../../tasks/exceptions'; import { CONFIRM_BTN } from '../../../screens/exceptions'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { ALERTS_COUNT } from '../../../screens/alerts'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts index 136038f641ec..511343abc8a7 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/entry/multiple_conditions.cy.ts @@ -25,7 +25,7 @@ import { EXCEPTION_ITEM_VIEWER_CONTAINER, } from '../../../screens/exceptions'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; describe( 'Add multiple conditions and validate the generated exceptions', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts index 8ec40a0e3643..e75c0eb8d81b 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_endpoint_exception.cy.ts @@ -30,7 +30,7 @@ import { deleteAlertsAndRules, deleteEndpointExceptionList, deleteExceptionLists, -} from '../../../tasks/common'; +} from '../../../tasks/api_calls/common'; import { NO_EXCEPTIONS_EXIST_PROMPT, EXCEPTION_ITEM_VIEWER_CONTAINER, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts index 6cc022873aea..a06b76455dfb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception.cy.ts @@ -37,7 +37,7 @@ import { submitEditedExceptionItem, submitNewExceptionItem, } from '../../../tasks/exceptions'; -import { deleteAlertsAndRules, deleteExceptionLists } from '../../../tasks/common'; +import { deleteAlertsAndRules, deleteExceptionLists } from '../../../tasks/api_calls/common'; import { NO_EXCEPTIONS_EXIST_PROMPT, EXCEPTION_ITEM_VIEWER_CONTAINER, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts index 79f6638e6c0f..a4f0daa190e4 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/add_edit_exception_data_view.cy.ts @@ -28,7 +28,7 @@ import { waitForTheRuleToBeExecuted, } from '../../../tasks/rule_details'; -import { postDataView, deleteAlertsAndRules } from '../../../tasks/common'; +import { postDataView, deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { NO_EXCEPTIONS_EXIST_PROMPT, EXCEPTION_ITEM_VIEWER_CONTAINER, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts index 935668db1a5a..9002e9569b4f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/rule_details_flow/read_only_view.cy.ts @@ -13,7 +13,7 @@ import { login } from '../../../tasks/login'; import { visitRulesManagementTable } from '../../../tasks/rules_management'; import { goToExceptionsTab, goToAlertsTab } from '../../../tasks/rule_details'; import { goToRuleDetailsOf } from '../../../tasks/alerts_detection_rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { NO_EXCEPTIONS_EXIST_PROMPT, EXCEPTION_ITEM_VIEWER_CONTAINER, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts index 9f64fac5f151..2b9b200ae6c2 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/manage_exceptions.cy.ts @@ -40,7 +40,7 @@ import { findSharedExceptionListItemsByName, } from '../../../tasks/exceptions_table'; import { visitRuleDetailsPage } from '../../../tasks/rule_details'; -import { deleteEndpointExceptionList, deleteExceptionLists } from '../../../tasks/common'; +import { deleteEndpointExceptionList, deleteExceptionLists } from '../../../tasks/api_calls/common'; // https://github.com/elastic/kibana/issues/171235 // FLAKY: https://github.com/elastic/kibana/issues/171242 diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts index af8edaa017b8..a4c251617b5f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/exceptions/shared_exception_lists_management/shared_exception_list_page/duplicate_lists.cy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { deleteAlertsAndRules, deleteExceptionLists } from '../../../../tasks/common'; +import { deleteAlertsAndRules, deleteExceptionLists } from '../../../../tasks/api_calls/common'; import { createRule } from '../../../../tasks/api_calls/rules'; import { getExceptionList } from '../../../../objects/exception'; import { assertNumberOfExceptionItemsExists } from '../../../../tasks/exceptions'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/attach_timeline.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/attach_timeline.cy.ts index e040c9873098..c0a2295887a1 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/attach_timeline.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/attach_timeline.cy.ts @@ -17,7 +17,7 @@ import { DESCRIPTION_INPUT, ADD_COMMENT_INPUT } from '../../../screens/create_ne import { getCase1 } from '../../../objects/case'; import { getTimeline } from '../../../objects/timeline'; import { createTimeline } from '../../../tasks/api_calls/timelines'; -import { deleteTimelines } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; import { createCase } from '../../../tasks/api_calls/cases'; describe('attach timeline to case', { tags: ['@ess', '@serverless'] }, () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connectors.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connectors.cy.ts index aaa785cc8f39..31c2068b49db 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connectors.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/connectors.cy.ts @@ -10,7 +10,7 @@ import { getServiceNowConnector, getServiceNowITSMHealthResponse } from '../../. import { SERVICE_NOW_MAPPING } from '../../../screens/configure_cases'; import { goToEditExternalConnection } from '../../../tasks/all_cases'; -import { deleteAllCasesItems, deleteConnectors } from '../../../tasks/common'; +import { deleteAllCasesItems, deleteConnectors } from '../../../tasks/api_calls/common'; import { addServiceNowConnector, openAddNewConnectorOption, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/privileges.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/privileges.cy.ts index f1cdbc0d7af9..341a75fe4b6f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/privileges.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/cases/privileges.cy.ts @@ -9,7 +9,7 @@ import type { TestCaseWithoutTimeline } from '../../../objects/case'; import { ALL_CASES_CREATE_NEW_CASE_BTN, ALL_CASES_NAME } from '../../../screens/all_cases'; import { goToCreateNewCase } from '../../../tasks/all_cases'; -import { deleteAllCasesItems } from '../../../tasks/common'; +import { deleteAllCasesItems } from '../../../tasks/api_calls/common'; import { backToCases, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/dashboards/entity_analytics.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/dashboards/entity_analytics.cy.ts index 7210bacd1aa7..e849e0408c07 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/dashboards/entity_analytics.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/dashboards/entity_analytics.cy.ts @@ -11,7 +11,7 @@ import { visitWithTimeRange } from '../../../tasks/navigation'; import { ALERTS_URL, ENTITY_ANALYTICS_URL } from '../../../urls/navigation'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { ANOMALIES_TABLE, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/explore/filters/pinned_filters.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/filters/pinned_filters.cy.ts index a9615f27984e..516b776a86e3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/explore/filters/pinned_filters.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/filters/pinned_filters.cy.ts @@ -21,7 +21,7 @@ import { openKibanaNavigation, } from '../../../tasks/kibana_navigation'; import { ALERTS_PAGE } from '../../../screens/kibana_navigation'; -import { postDataView } from '../../../tasks/common'; +import { postDataView } from '../../../tasks/api_calls/common'; import { navigateToAlertsPageInServerless } from '../../../tasks/serverless/navigation'; describe('ESS - pinned filters', { tags: ['@ess'] }, () => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/inspect/inspect_button.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/inspect/inspect_button.cy.ts similarity index 85% rename from x-pack/test/security_solution_cypress/cypress/e2e/inspect/inspect_button.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/inspect/inspect_button.cy.ts index 30a3704879f3..86309e80fd7e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/inspect/inspect_button.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/inspect/inspect_button.cy.ts @@ -9,17 +9,18 @@ import { INSPECT_BUTTONS_IN_SECURITY, INSPECT_MODAL, INSPECT_MODAL_INDEX_PATTERN, -} from '../../screens/inspect'; +} from '../../../screens/inspect'; import { closesModal, openLensVisualizationsInspectModal, openTab, openTableInspectModal, -} from '../../tasks/inspect'; -import { login } from '../../tasks/login'; -import { visitWithTimeRange } from '../../tasks/navigation'; -import { postDataView, waitForWelcomePanelToBeLoaded } from '../../tasks/common'; -import { selectDataView } from '../../tasks/sourcerer'; +} from '../../../tasks/inspect'; +import { login } from '../../../tasks/login'; +import { visitWithTimeRange } from '../../../tasks/navigation'; +import { waitForWelcomePanelToBeLoaded } from '../../../tasks/common'; +import { selectDataView } from '../../../tasks/sourcerer'; +import { postDataView } from '../../../tasks/api_calls/common'; const DATA_VIEW = 'auditbeat-*'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/ml/ml_conditional_links.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/ml/ml_conditional_links.cy.ts similarity index 98% rename from x-pack/test/security_solution_cypress/cypress/e2e/ml/ml_conditional_links.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/ml/ml_conditional_links.cy.ts index 061f17032c54..c90f8bea96fd 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/ml/ml_conditional_links.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/ml/ml_conditional_links.cy.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { KQL_INPUT } from '../../screens/security_header'; +import { KQL_INPUT } from '../../../screens/security_header'; -import { login } from '../../tasks/login'; -import { visit } from '../../tasks/navigation'; +import { login } from '../../../tasks/login'; +import { visit } from '../../../tasks/navigation'; import { mlHostMultiHostKqlQuery, @@ -24,7 +24,7 @@ import { mlNetworkNullKqlQuery, mlNetworkSingleIpKqlQuery, mlNetworkSingleIpNullKqlQuery, -} from '../../urls/ml_conditional_links'; +} from '../../../urls/ml_conditional_links'; describe('ml conditional links', { tags: ['@ess', '@brokenInServerless'] }, () => { beforeEach(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/navigation/navigation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/navigation.cy.ts similarity index 96% rename from x-pack/test/security_solution_cypress/cypress/e2e/navigation/navigation.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/navigation.cy.ts index 788ff1d9eac0..906dcd0548b3 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/navigation/navigation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/navigation.cy.ts @@ -30,12 +30,12 @@ import { EXPLORE, SETTINGS, ENTITY_ANALYTICS, -} from '../../screens/security_header'; -import * as ServerlessHeaders from '../../screens/serverless_security_header'; +} from '../../../screens/security_header'; +import * as ServerlessHeaders from '../../../screens/serverless_security_header'; -import { login } from '../../tasks/login'; -import { visit, visitGetStartedPage, visitWithTimeRange } from '../../tasks/navigation'; -import { navigateFromHeaderTo } from '../../tasks/security_header'; +import { login } from '../../../tasks/login'; +import { visit, visitGetStartedPage, visitWithTimeRange } from '../../../tasks/navigation'; +import { navigateFromHeaderTo } from '../../../tasks/security_header'; import { ALERTS_URL, @@ -71,12 +71,12 @@ import { ASSETS_URL, FLEET_URL, CLOUD_DEFEND_URL, -} from '../../urls/navigation'; -import { RULES_MANAGEMENT_URL } from '../../urls/rules_management'; +} from '../../../urls/navigation'; +import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; import { openKibanaNavigation, navigateFromKibanaCollapsibleTo, -} from '../../tasks/kibana_navigation'; +} from '../../../tasks/kibana_navigation'; import { CASES_PAGE, ALERTS_PAGE, @@ -86,7 +86,7 @@ import { TIMELINES_PAGE, FINDINGS_PAGE, THREAT_INTELLIGENCE_PAGE, -} from '../../screens/kibana_navigation'; +} from '../../../screens/kibana_navigation'; describe('top-level navigation common to all pages in the Security app', { tags: '@ess' }, () => { beforeEach(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/navigation/search_bar.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/search_bar.cy.ts similarity index 76% rename from x-pack/test/security_solution_cypress/cypress/e2e/navigation/search_bar.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/search_bar.cy.ts index a92e5aa1d93d..14afab3600f5 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/navigation/search_bar.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/navigation/search_bar.cy.ts @@ -5,23 +5,23 @@ * 2.0. */ -import { login } from '../../tasks/login'; -import { visitWithTimeRange } from '../../tasks/navigation'; +import { login } from '../../../tasks/login'; +import { visitWithTimeRange } from '../../../tasks/navigation'; import { openAddFilterPopover, fillAddFilterForm, openKqlQueryBar, fillKqlQueryBar, -} from '../../tasks/search_bar'; +} from '../../../tasks/search_bar'; import { AUTO_SUGGEST_AGENT_NAME, AUTO_SUGGEST_HOST_NAME_VALUE, GLOBAL_SEARCH_BAR_FILTER_ITEM, -} from '../../screens/search_bar'; -import { getHostIpFilter } from '../../objects/filter'; +} from '../../../screens/search_bar'; +import { getHostIpFilter } from '../../../objects/filter'; -import { hostsUrl } from '../../urls/navigation'; -import { waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; +import { hostsUrl } from '../../../urls/navigation'; +import { waitForAllHostsToBeLoaded } from '../../../tasks/hosts/all_hosts'; describe('SearchBar', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/urls/compatibility.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/compatibility.cy.ts similarity index 85% rename from x-pack/test/security_solution_cypress/cypress/e2e/urls/compatibility.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/compatibility.cy.ts index 856f11227275..fa11642abc17 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/urls/compatibility.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/compatibility.cy.ts @@ -5,18 +5,18 @@ * 2.0. */ -import { login } from '../../tasks/login'; -import { visit } from '../../tasks/navigation'; +import { login } from '../../../tasks/login'; +import { visit } from '../../../tasks/navigation'; -import { ALERTS_URL, CREATE_RULE_URL } from '../../urls/navigation'; -import { RULES_MANAGEMENT_URL } from '../../urls/rules_management'; -import { ABSOLUTE_DATE_RANGE } from '../../urls/state'; +import { ALERTS_URL, CREATE_RULE_URL } from '../../../urls/navigation'; +import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; +import { ABSOLUTE_DATE_RANGE } from '../../../urls/state'; import { DATE_PICKER_START_DATE_POPOVER_BUTTON, GET_DATE_PICKER_END_DATE_POPOVER_BUTTON, -} from '../../screens/date_picker'; -import { ruleDetailsUrl } from '../../urls/rule_details'; -import { editRuleUrl } from '../../urls/edit_rule'; +} from '../../../screens/date_picker'; +import { ruleDetailsUrl } from '../../../urls/rule_details'; +import { editRuleUrl } from '../../../urls/edit_rule'; const LEGACY_DETECTIONS_URL_1 = '/app/siem#/detections'; const LEGACY_DETECTIONS_URL_2 = '/app/security/detections'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/urls/not_found.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts similarity index 85% rename from x-pack/test/security_solution_cypress/cypress/e2e/urls/not_found.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts index 329e0b33144b..9c27440a9786 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/urls/not_found.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/not_found.cy.ts @@ -5,8 +5,8 @@ * 2.0. */ -import { login } from '../../tasks/login'; -import { visitWithTimeRange } from '../../tasks/navigation'; +import { login } from '../../../tasks/login'; +import { visitWithTimeRange } from '../../../tasks/navigation'; import { ALERTS_URL, @@ -16,12 +16,12 @@ import { TIMELINES_URL, EXCEPTIONS_URL, CREATE_RULE_URL, -} from '../../urls/navigation'; -import { RULES_MANAGEMENT_URL } from '../../urls/rules_management'; +} from '../../../urls/navigation'; +import { RULES_MANAGEMENT_URL } from '../../../urls/rules_management'; -import { NOT_FOUND } from '../../screens/common/page'; -import { ruleDetailsUrl } from '../../urls/rule_details'; -import { editRuleUrl } from '../../urls/edit_rule'; +import { NOT_FOUND } from '../../../screens/common/page'; +import { ruleDetailsUrl } from '../../../urls/rule_details'; +import { editRuleUrl } from '../../../urls/edit_rule'; const mockRuleId = '5a4a0460-d822-11eb-8962-bfd4aff0a9b3'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/urls/state.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/state.cy.ts similarity index 92% rename from x-pack/test/security_solution_cypress/cypress/e2e/urls/state.cy.ts rename to x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/state.cy.ts index 0f2d2ad9cac3..e24998fd9f30 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/urls/state.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/explore/urls/state.cy.ts @@ -11,9 +11,9 @@ import { GET_LOCAL_DATE_PICKER_END_DATE_POPOVER_BUTTON, DATE_PICKER_START_DATE_POPOVER_BUTTON, GET_LOCAL_DATE_PICKER_START_DATE_POPOVER_BUTTON, -} from '../../screens/date_picker'; -import { HOSTS_NAMES } from '../../screens/hosts/all_hosts'; -import { ANOMALIES_TAB } from '../../screens/hosts/main'; +} from '../../../screens/date_picker'; +import { HOSTS_NAMES } from '../../../screens/hosts/all_hosts'; +import { ANOMALIES_TAB } from '../../../screens/hosts/main'; import { BREADCRUMBS, EXPLORE_PANEL_BTN, @@ -22,38 +22,38 @@ import { NETWORK, LOADING_INDICATOR, openNavigationPanel, -} from '../../screens/security_header'; -import { TIMELINE_DATE_PICKER_CONTAINER, TIMELINE_TITLE } from '../../screens/timeline'; +} from '../../../screens/security_header'; +import { TIMELINE_DATE_PICKER_CONTAINER, TIMELINE_TITLE } from '../../../screens/timeline'; -import { login } from '../../tasks/login'; -import { visit, visitWithTimeRange } from '../../tasks/navigation'; +import { login } from '../../../tasks/login'; +import { visit, visitWithTimeRange } from '../../../tasks/navigation'; import { updateDates, setStartDate, setEndDate, updateTimelineDates, -} from '../../tasks/date_picker'; -import { openFirstHostDetails, waitForAllHostsToBeLoaded } from '../../tasks/hosts/all_hosts'; -import { openAllHosts } from '../../tasks/hosts/main'; +} from '../../../tasks/date_picker'; +import { openFirstHostDetails, waitForAllHostsToBeLoaded } from '../../../tasks/hosts/all_hosts'; +import { openAllHosts } from '../../../tasks/hosts/main'; -import { waitForIpsTableToBeLoaded } from '../../tasks/network/flows'; +import { waitForIpsTableToBeLoaded } from '../../../tasks/network/flows'; import { clearSearchBar, kqlSearch, navigateFromHeaderTo, saveQuery, -} from '../../tasks/security_header'; -import { openTimelineUsingToggle } from '../../tasks/security_main'; -import { addNameToTimelineAndSave, closeTimeline, populateTimeline } from '../../tasks/timeline'; +} from '../../../tasks/security_header'; +import { openTimelineUsingToggle } from '../../../tasks/security_main'; +import { addNameToTimelineAndSave, closeTimeline, populateTimeline } from '../../../tasks/timeline'; -import { hostsUrl } from '../../urls/navigation'; -import { ABSOLUTE_DATE_RANGE } from '../../urls/state'; +import { hostsUrl } from '../../../urls/navigation'; +import { ABSOLUTE_DATE_RANGE } from '../../../urls/state'; -import { getTimeline } from '../../objects/timeline'; +import { getTimeline } from '../../../objects/timeline'; import { GLOBAL_SEARCH_BAR_FILTER_ITEM_AT, GLOBAL_SEARCH_BAR_PINNED_FILTER, -} from '../../screens/search_bar'; +} from '../../../screens/search_bar'; const ABSOLUTE_DATE = { endTime: 'Aug 1, 2019 @ 20:33:29.186', diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts index 9ab0d0756942..7e5e19b464c4 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_details.cy.ts @@ -25,7 +25,7 @@ import { openTable, } from '../../../tasks/alerts_details'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit, visitWithTimeRange } from '../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_table_api_calls.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_table_api_calls.cy.ts new file mode 100644 index 000000000000..3ef2c0dd21b6 --- /dev/null +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/alerts_table_api_calls.cy.ts @@ -0,0 +1,48 @@ +/* + * 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 { getNewRule } from '../../../objects/rule'; +import { createRule } from '../../../tasks/api_calls/rules'; +import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; +import { login } from '../../../tasks/login'; +import { visit } from '../../../tasks/navigation'; +import { ALERTS_URL } from '../../../urls/navigation'; + +/* + * + * Alert table is third party component which cannot be easily tested by jest. + * This test main checks if Alert Table does not call api/lists/index more than once. + * + * */ + +describe('Alert Table API calls', { tags: ['@ess', '@serverless'] }, () => { + let callCount: number = 0; + + beforeEach(() => { + callCount = 0; + login(); + createRule(getNewRule()); + // intercept all calls to `api/lists/index` + // and count how many times it was called + cy.intercept('GET', '/api/lists/index', (req) => { + req.on('response', (res) => { + if (res.statusCode === 200) { + callCount += 1; + } + }); + }); + + visit(ALERTS_URL); + waitForAlertsToPopulate(); + }); + + it('should call `api/lists/index` only once', () => { + cy.get('[data-test-subj="alertsTable"]').then(() => { + expect(callCount, 'number of times lists index api is called').to.equal(1); + }); + }); +}); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts index f06fad0cd43e..2dc4a360134b 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/changing_alert_status.cy.ts @@ -32,7 +32,7 @@ import { parseAlertsCountToInt, } from '../../../tasks/alerts'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { waitForAlertsToPopulate } from '../../../tasks/create_new_rule'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts index dd29284f6c0c..1097a8357167 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/detection_page_filters.cy.ts @@ -51,7 +51,7 @@ import { import { TOASTER } from '../../../screens/alerts_detection_rules'; import { setEndDate, setStartDate } from '../../../tasks/date_picker'; import { fillAddFilterForm, openAddFilterPopover } from '../../../tasks/search_bar'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; const customFilters = [ { @@ -107,7 +107,8 @@ const assertFilterControlsWithFilterObject = ( }); }; -describe(`Detections : Page Filters`, { tags: ['@ess', '@serverless'] }, () => { +// FLAKY: https://github.com/elastic/kibana/issues/171890 +describe.skip(`Detections : Page Filters`, { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { deleteAlertsAndRules(); createRule(getNewRule({ rule_id: 'custom_rule_filters' })); diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel.cy.ts index 6e0b437f2e2e..aaa8806362d0 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel.cy.ts @@ -51,7 +51,7 @@ import { openTakeActionButtonAndSelectItem, selectTakeActionItem, } from '../../../../tasks/expandable_flyout/alert_details_right_panel'; -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { login } from '../../../../tasks/login'; import { visit } from '../../../../tasks/navigation'; import { createRule } from '../../../../tasks/api_calls/rules'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts index 33bcb93caacf..fb2af6a16b02 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { collapseDocumentDetailsExpandableFlyoutLeftSection } from '../../../../tasks/expandable_flyout/alert_details_right_panel'; import { createNewCaseFromExpandableFlyout, diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_table_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_table_tab.cy.ts index aa320000a256..c855beca9fdb 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_table_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_table_tab.cy.ts @@ -25,7 +25,7 @@ import { filterTableTabTable, toggleColumnTableTabTable, } from '../../../../tasks/expandable_flyout/alert_details_right_panel_table_tab'; -import { deleteAlertsAndRules } from '../../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../../tasks/api_calls/common'; import { login } from '../../../../tasks/login'; import { visit } from '../../../../tasks/navigation'; import { createRule } from '../../../../tasks/api_calls/rules'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/ransomware_prevention.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/ransomware_prevention.cy.ts index 98d76d984512..b90413cdfe75 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/ransomware_prevention.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/alerts/ransomware_prevention.cy.ts @@ -12,7 +12,7 @@ import { ALERTS_URL } from '../../../urls/navigation'; import { ALERTS_HISTOGRAM_SERIES, ALERT_RULE_NAME, MESSAGE } from '../../../screens/alerts'; import { TIMELINE_VIEW_IN_ANALYZER } from '../../../screens/timeline'; import { selectAlertsHistogram } from '../../../tasks/alerts'; -import { deleteTimelines } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; import { createTimeline } from '../../../tasks/api_calls/timelines'; import { getTimeline } from '../../../objects/timeline'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/dasbhoards/detection_response.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/dasbhoards/detection_response.cy.ts index e19e4ca043b3..eb3881f8123a 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/dasbhoards/detection_response.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/dasbhoards/detection_response.cy.ts @@ -31,7 +31,7 @@ import { import { QUERY_TAB_BUTTON, TIMELINE_DATA_PROVIDERS_CONTAINER } from '../../../screens/timeline'; import { waitForAlerts } from '../../../tasks/alerts'; import { createRule } from '../../../tasks/api_calls/rules'; -import { deleteAlertsAndRules } from '../../../tasks/common'; +import { deleteAlertsAndRules } from '../../../tasks/api_calls/common'; import { investigateDashboardItemInTimeline } from '../../../tasks/dashboards/common'; import { waitToNavigateAwayFrom } from '../../../tasks/kibana_navigation'; import { login } from '../../../tasks/login'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timeline_templates/creation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timeline_templates/creation.cy.ts index b3ed43ffe9d8..bb1e0f372e33 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timeline_templates/creation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timeline_templates/creation.cy.ts @@ -26,7 +26,7 @@ import { TIMELINES_FAVORITE, } from '../../../screens/timelines'; import { createTimeline } from '../../../tasks/api_calls/timelines'; -import { deleteTimelines } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visit } from '../../../tasks/navigation'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/correlation_tab.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/correlation_tab.cy.ts index a50dbe08b063..96b30a29d23d 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/correlation_tab.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/correlation_tab.cy.ts @@ -21,7 +21,7 @@ import { addEqlToTimeline, saveTimeline } from '../../../tasks/timeline'; import { TIMELINES_URL } from '../../../urls/navigation'; import { EQL_QUERY_VALIDATION_ERROR } from '../../../screens/create_new_rule'; -import { deleteTimelines } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; describe('Correlation tab', { tags: ['@ess', '@serverless'] }, () => { const eql = 'any where process.name == "zsh"'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/creation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/creation.cy.ts index 546cdaa6b64c..e324dede796f 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/creation.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/creation.cy.ts @@ -24,7 +24,7 @@ import { } from '../../../screens/timeline'; import { createTimelineTemplate } from '../../../tasks/api_calls/timelines'; -import { deleteTimelines } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; import { login } from '../../../tasks/login'; import { visit, visitWithTimeRange } from '../../../tasks/navigation'; import { openTimelineUsingToggle } from '../../../tasks/security_main'; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts index ba20f89defef..80d4a9780c6e 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/investigations/timelines/row_renderers.cy.ts @@ -16,7 +16,8 @@ import { TIMELINE_ROW_RENDERERS_SURICATA_LINK_TOOLTIP, TIMELINE_ROW_RENDERERS_MODAL_CLOSE_BUTTON, } from '../../../screens/timeline'; -import { deleteTimelines, waitForWelcomePanelToBeLoaded } from '../../../tasks/common'; +import { deleteTimelines } from '../../../tasks/api_calls/common'; +import { waitForWelcomePanelToBeLoaded } from '../../../tasks/common'; import { waitForAllHostsToBeLoaded } from '../../../tasks/hosts/all_hosts'; import { login } from '../../../tasks/login'; diff --git a/x-pack/test/security_solution_cypress/cypress/objects/exception.ts b/x-pack/test/security_solution_cypress/cypress/objects/exception.ts index 6e754d837dcf..6865784ae5ba 100644 --- a/x-pack/test/security_solution_cypress/cypress/objects/exception.ts +++ b/x-pack/test/security_solution_cypress/cypress/objects/exception.ts @@ -6,6 +6,7 @@ */ import type { ExceptionListSchema } from '@kbn/securitysolution-io-ts-list-types'; +import { ELASTICSEARCH_USERNAME } from '../env_var_names_constants'; export interface Exception { field: string; @@ -61,5 +62,15 @@ export const expectedExportedExceptionList = ( exceptionListResponse: Cypress.Response ): string => { const jsonRule = exceptionListResponse.body; - return `{"_version":"${jsonRule._version}","created_at":"${jsonRule.created_at}","created_by":"system_indices_superuser","description":"${jsonRule.description}","id":"${jsonRule.id}","immutable":false,"list_id":"${jsonRule.list_id}","name":"${jsonRule.name}","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"${jsonRule.tie_breaker_id}","type":"${jsonRule.type}","updated_at":"${jsonRule.updated_at}","updated_by":"system_indices_superuser","version":1}\n{"exported_exception_list_count":1,"exported_exception_list_item_count":0,"missing_exception_list_item_count":0,"missing_exception_list_items":[],"missing_exception_lists":[],"missing_exception_lists_count":0}\n`; + return `{"_version":"${jsonRule._version}","created_at":"${ + jsonRule.created_at + }","created_by":"${Cypress.env(ELASTICSEARCH_USERNAME)}","description":"${ + jsonRule.description + }","id":"${jsonRule.id}","immutable":false,"list_id":"${jsonRule.list_id}","name":"${ + jsonRule.name + }","namespace_type":"single","os_types":[],"tags":[],"tie_breaker_id":"${ + jsonRule.tie_breaker_id + }","type":"${jsonRule.type}","updated_at":"${jsonRule.updated_at}","updated_by":"${Cypress.env( + ELASTICSEARCH_USERNAME + )}","version":1}\n{"exported_exception_list_count":1,"exported_exception_list_item_count":0,"missing_exception_list_item_count":0,"missing_exception_list_items":[],"missing_exception_lists":[],"missing_exception_lists_count":0}\n`; }; diff --git a/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts b/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts index e1dc4c952eac..02ebebb6c10e 100644 --- a/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts +++ b/x-pack/test/security_solution_cypress/cypress/support/setup_users.ts @@ -6,7 +6,7 @@ */ import { Role } from '@kbn/security-plugin/common'; -import { rootRequest } from '../tasks/common'; +import { rootRequest } from '../tasks/api_calls/common'; /** * Utility function creates roles and corresponding users per each role with names diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/alerts.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/alerts.ts index 43d9952b9b37..3b9c0612a072 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/alerts.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/alerts.ts @@ -9,7 +9,7 @@ import { RuleObjectId, RuleSignatureId, } from '@kbn/security-solution-plugin/common/api/detection_engine'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const DEFAULT_ALERTS_INDEX_PATTERN = '.alerts-security.alerts-*'; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/common.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/common.ts new file mode 100644 index 000000000000..775b4c5a8964 --- /dev/null +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/common.ts @@ -0,0 +1,264 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DATA_VIEW_PATH, INITIAL_REST_VERSION } from '@kbn/data-views-plugin/server/constants'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { ELASTICSEARCH_PASSWORD, ELASTICSEARCH_USERNAME } from '../../env_var_names_constants'; +import { deleteAllDocuments } from './elasticsearch'; +import { DEFAULT_ALERTS_INDEX_PATTERN } from './alerts'; + +export const API_AUTH = Object.freeze({ + user: Cypress.env(ELASTICSEARCH_USERNAME), + pass: Cypress.env(ELASTICSEARCH_PASSWORD), +}); + +export const API_HEADERS = Object.freeze({ + 'kbn-xsrf': 'cypress-creds', + 'x-elastic-internal-origin': 'security-solution', + [ELASTIC_HTTP_VERSION_HEADER]: [INITIAL_REST_VERSION], +}); + +export const rootRequest = ({ + headers: optionHeaders, + ...restOptions +}: Partial): Cypress.Chainable> => + cy.request({ + auth: API_AUTH, + headers: { + ...API_HEADERS, + ...(optionHeaders || {}), + }, + ...restOptions, + }); + +export const deleteAlertsAndRules = () => { + cy.log('Delete all alerts and rules'); + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + + rootRequest({ + method: 'POST', + url: '/api/detection_engine/rules/_bulk_action', + body: { + query: '', + action: 'delete', + }, + failOnStatusCode: false, + timeout: 300000, + }); + + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'alert', + }, + }, + ], + }, + }, + }, + }); + + deleteAllDocuments(`.lists-*,.items-*,${DEFAULT_ALERTS_INDEX_PATTERN}`); +}; + +export const deleteExceptionLists = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'exception-list', + }, + }, + ], + }, + }, + }, + }); +}; + +export const deleteEndpointExceptionList = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'exception-list-agnostic', + }, + }, + ], + }, + }, + }, + }); +}; + +export const deleteTimelines = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'siem-ui-timeline', + }, + }, + ], + }, + }, + }, + }); +}; + +export const deleteAlertsIndex = () => { + rootRequest({ + method: 'POST', + url: '/api/index_management/indices/delete', + body: { indices: ['.internal.alerts-security.alerts-default-000001'] }, + failOnStatusCode: false, + }); +}; + +export const deleteAllCasesItems = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_alerting_cases_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + bool: { + should: [ + { + term: { + type: 'cases', + }, + }, + { + term: { + type: 'cases-configure', + }, + }, + { + term: { + type: 'cases-comments', + }, + }, + { + term: { + type: 'cases-user-action', + }, + }, + { + term: { + type: 'cases-connector-mappings', + }, + }, + ], + }, + }, + ], + }, + }, + }, + }); +}; + +export const deleteConnectors = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_alerting_cases_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'action', + }, + }, + ], + }, + }, + }, + }); +}; + +export const deletePrebuiltRulesAssets = () => { + const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; + rootRequest({ + method: 'POST', + url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, + body: { + query: { + bool: { + filter: [ + { + match: { + type: 'security-rule', + }, + }, + ], + }, + }, + }, + }); +}; + +export const postDataView = (indexPattern: string, name?: string, id?: string) => { + rootRequest({ + method: 'POST', + url: DATA_VIEW_PATH, + body: { + data_view: { + id: id || indexPattern, + name: name || indexPattern, + fieldAttrs: '{}', + title: indexPattern, + timeFieldName: '@timestamp', + }, + }, + failOnStatusCode: false, + }); +}; + +export const deleteDataView = (dataViewId: string) => { + rootRequest({ + method: 'POST', + url: 'api/content_management/rpc/delete', + body: { + contentTypeId: 'index-pattern', + id: dataViewId, + options: { force: true }, + version: 1, + }, + failOnStatusCode: false, + }); +}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/elasticsearch.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/elasticsearch.ts index d94049f14c8a..6dc3622f72a0 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/elasticsearch.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/elasticsearch.ts @@ -4,17 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const deleteIndex = (index: string) => { rootRequest({ method: 'DELETE', url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); }; @@ -23,11 +18,6 @@ export const deleteDataStream = (dataStreamName: string) => { rootRequest({ method: 'DELETE', url: `${Cypress.env('ELASTICSEARCH_URL')}/_data_stream/${dataStreamName}`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); }; @@ -40,11 +30,6 @@ export const deleteAllDocuments = (target: string) => { url: `${Cypress.env( 'ELASTICSEARCH_URL' )}/${target}/_delete_by_query?conflicts=proceed&scroll_size=10000&refresh`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, body: { query: { match_all: {}, @@ -57,11 +42,6 @@ export const createIndex = (indexName: string, properties: Record({ method: 'GET', url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_search`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }).then((response) => { if (response.status !== 200) { @@ -110,11 +80,6 @@ export const refreshIndex = (index: string) => { rootRequest({ method: 'POST', url: `${Cypress.env('ELASTICSEARCH_URL')}/${index}/_refresh`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }).then((response) => { if (response.status !== 200) { diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/exceptions.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/exceptions.ts index 8b7d85b7ebf4..4e0afa7416da 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/exceptions.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/exceptions.ts @@ -13,17 +13,12 @@ import type { } from '@kbn/securitysolution-io-ts-list-types'; import { ENDPOINT_LIST_ITEM_URL, ENDPOINT_LIST_URL } from '@kbn/securitysolution-list-constants'; import type { ExceptionList, ExceptionListItem, RuleExceptionItem } from '../../objects/exception'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const createEndpointExceptionList = () => rootRequest({ method: 'POST', url: ENDPOINT_LIST_URL, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); export const createEndpointExceptionListItem = (item: CreateEndpointListItemSchema) => @@ -31,11 +26,6 @@ export const createEndpointExceptionListItem = (item: CreateEndpointListItemSche method: 'POST', url: ENDPOINT_LIST_ITEM_URL, body: item, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); export const createExceptionList = ( @@ -51,11 +41,6 @@ export const createExceptionList = ( name: exceptionList.name, type: exceptionList.type, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); @@ -88,11 +73,6 @@ export const createExceptionListItem = ( ], expire_time: exceptionListItem?.expire_time, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); @@ -103,11 +83,6 @@ export const createRuleExceptionItem = (ruleId: string, exceptionListItems: Rule body: { items: exceptionListItems, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); @@ -122,11 +97,6 @@ export const updateExceptionListItem = ( item_id: exceptionListItemId, ...exceptionListItemUpdate, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); @@ -134,10 +104,5 @@ export const deleteExceptionList = (listId: string, namespaceType: string) => rootRequest({ method: 'DELETE', url: `/api/exception_lists?list_id=${listId}&namespace_type=${namespaceType}`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/fleet.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/fleet.ts index 5295b033fc7c..d77361c95ebd 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/fleet.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/fleet.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { rootRequest } from '../common'; +import { rootRequest } from './common'; /** * Deletes all existing Fleet packages, package policies and agent policies. @@ -25,21 +25,11 @@ const deleteAgentPolicies = () => { return rootRequest<{ items: Array<{ id: string }> }>({ method: 'GET', url: 'api/fleet/agent_policies', - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }).then((response) => { response.body.items.forEach((item: { id: string }) => { rootRequest({ method: 'POST', url: `api/fleet/agent_policies/delete`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, body: { agentPolicyId: item.id, }, @@ -52,20 +42,10 @@ const deletePackagePolicies = () => { return rootRequest<{ items: Array<{ id: string }> }>({ method: 'GET', url: 'api/fleet/package_policies', - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }).then((response) => { rootRequest({ method: 'POST', url: `api/fleet/package_policies/delete`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, body: { packagePolicyIds: response.body.items.map((item: { id: string }) => item.id), }, @@ -77,22 +57,12 @@ const deletePackages = () => { return rootRequest<{ items: Array<{ status: string; name: string; version: string }> }>({ method: 'GET', url: 'api/fleet/epm/packages', - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }).then((response) => { response.body.items.forEach((item) => { if (item.status === 'installed') { rootRequest({ method: 'DELETE', url: `api/fleet/epm/packages/${item.name}/${item.version}`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); } }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/integrations.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/integrations.ts similarity index 83% rename from x-pack/test/security_solution_cypress/cypress/tasks/integrations.ts rename to x-pack/test/security_solution_cypress/cypress/tasks/api_calls/integrations.ts index eeef97682b9c..4e212d4b8eb3 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/integrations.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/integrations.ts @@ -56,11 +56,6 @@ export function installIntegrations({ packages, force: true, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); // Install agent and package policies @@ -68,11 +63,6 @@ export function installIntegrations({ method: 'POST', url: `${AGENT_POLICY_API_ROUTES.CREATE_PATTERN}?sys_monitoring=true`, body: agentPolicy, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }).then((response) => { const packagePolicyWithAgentPolicyId: PackagePolicy = { ...packagePolicy, @@ -83,11 +73,6 @@ export function installIntegrations({ method: 'POST', url: PACKAGE_POLICY_API_ROUTES.CREATE_PATTERN, body: packagePolicyWithAgentPolicyId, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); }); } diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts index 2c982adad527..27d5063ce30d 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/kibana_advanced_settings.ts @@ -7,14 +7,13 @@ import { SECURITY_SOLUTION_SHOW_RELATED_INTEGRATIONS_ID } from '@kbn/management-settings-ids'; import { ENABLE_EXPANDABLE_FLYOUT_SETTING } from '@kbn/security-solution-plugin/common/constants'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const setKibanaSetting = (key: string, value: boolean | number | string) => { rootRequest({ method: 'POST', url: 'internal/kibana/settings', body: { changes: { [key]: value } }, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, }); }; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/machine_learning.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/machine_learning.ts index afb468876c5f..f03d6edadbc1 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/machine_learning.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/machine_learning.ts @@ -7,17 +7,12 @@ import { ML_INTERNAL_BASE_PATH } from '@kbn/ml-plugin/common/constants/app'; import type { Module } from '@kbn/ml-plugin/common/types/modules'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const fetchMachineLearningModules = () => { return rootRequest({ method: 'GET', url: `${ML_INTERNAL_BASE_PATH}/modules/get_module`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': 1, - }, failOnStatusCode: false, }); }; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts index 98b9a884e683..273491ebd2ef 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/prebuilt_rules.ts @@ -13,17 +13,12 @@ import { ELASTIC_SECURITY_RULE_ID } from '@kbn/security-solution-plugin/common/d import type { PrePackagedRulesStatusResponse } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types'; import { getPrebuiltRuleWithExceptionsMock } from '@kbn/security-solution-plugin/server/lib/detection_engine/prebuilt_rules/mocks'; import { createRuleAssetSavedObject } from '../../helpers/rules'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const getPrebuiltRulesStatus = () => { return rootRequest({ method: 'GET', url: 'api/detection_engine/rules/prepackaged/_status', - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); }; @@ -43,14 +38,12 @@ export const installAllPrebuiltRulesRequest = () => rootRequest({ method: 'POST', url: PERFORM_RULE_INSTALLATION_URL, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '1', - }, body: { mode: 'ALL_RULES', }, + headers: { + 'elastic-api-version': '1', + }, }); /* Install specific prebuilt rules. Should be available as security-rule saved objects @@ -63,11 +56,6 @@ export const installSpecificPrebuiltRulesRequest = (rules: Array({ method: 'POST', url: PERFORM_RULE_INSTALLATION_URL, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '1', - }, body: { mode: 'SPECIFIC_RULES', rules: rules.map((rule) => ({ @@ -75,6 +63,9 @@ export const installSpecificPrebuiltRulesRequest = (rules: Array { @@ -128,8 +119,6 @@ export const createNewRuleAsset = ({ method: 'PUT', url, headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', 'Content-Type': 'application/json', }, failOnStatusCode: false, @@ -182,7 +171,7 @@ export const bulkCreateRuleAssets = ({ return rootRequest({ method: 'POST', url, - headers: { 'kbn-xsrf': 'cypress-creds', 'Content-Type': 'application/json' }, + headers: { 'Content-Type': 'application/json' }, failOnStatusCode: false, body: bulkIndexRequestBody, }).then((response) => response.status === 200); @@ -197,8 +186,6 @@ export const getRuleAssets = (index: string | undefined = '.kibana_security_solu method: 'GET', url, headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', 'Content-Type': 'application/json', }, failOnStatusCode: false, diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts index 254d93cac507..5f89e57ff81c 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/rules.ts @@ -16,16 +16,11 @@ import type { } from '@kbn/security-solution-plugin/common/api/detection_engine'; import type { FetchRulesResponse } from '@kbn/security-solution-plugin/public/detection_engine/rule_management/logic/types'; import { internalAlertingSnoozeRule } from '../../urls/routes'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const findAllRules = () => { return rootRequest({ url: DETECTION_ENGINE_RULES_URL_FIND, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); }; @@ -36,11 +31,6 @@ export const createRule = ( method: 'POST', url: DETECTION_ENGINE_RULES_URL, body: rule, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); }; @@ -52,7 +42,7 @@ export const createRule = ( * @param duration Snooze duration in milliseconds, -1 for indefinite */ export const snoozeRule = (id: string, duration: number): Cypress.Chainable => - cy.request({ + rootRequest({ method: 'POST', url: internalAlertingSnoozeRule(id), body: { @@ -61,7 +51,6 @@ export const snoozeRule = (id: string, duration: number): Cypress.Chainable => rRule: { dtstart: new Date().toISOString(), count: 1, tzid: moment().format('zz') }, }, }, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, failOnStatusCode: false, }); @@ -69,11 +58,6 @@ export const deleteCustomRule = (ruleId = '1') => { rootRequest({ method: 'DELETE', url: `api/detection_engine/rules?rule_id=${ruleId}`, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, failOnStatusCode: false, }); }; @@ -89,10 +73,7 @@ export const importRule = (ndjsonPath: string) => { url: 'api/detection_engine/rules/_import', method: 'POST', headers: { - 'kbn-xsrf': 'cypress-creds', 'content-type': 'multipart/form-data', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', }, body: formdata, }) @@ -108,10 +89,7 @@ export const waitForRulesToFinishExecution = (ruleIds: string[], afterDate?: Dat method: 'GET', url: DETECTION_ENGINE_RULES_URL_FIND, headers: { - 'kbn-xsrf': 'cypress-creds', 'content-type': 'multipart/form-data', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', }, }).then((response) => { const areAllRulesFinished = ruleIds.every((ruleId) => diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/saved_queries.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/saved_queries.ts index 88049b20d6d5..0ec356e83727 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/saved_queries.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/saved_queries.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import type { SavedQuery } from '@kbn/data-plugin/public'; import { SAVED_QUERY_BASE_URL } from '@kbn/data-plugin/common/constants'; -import { rootRequest } from '../common'; +import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { rootRequest } from './common'; export const createSavedQuery = ( title: string, @@ -37,9 +37,7 @@ export const createSavedQuery = ( ], }, headers: { - 'kbn-xsrf': 'cypress-creds', [ELASTIC_HTTP_VERSION_HEADER]: '1', - 'x-elastic-internal-origin': 'security-solution', }, }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/sourcerer.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/sourcerer.ts new file mode 100644 index 000000000000..a266678ee95d --- /dev/null +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/sourcerer.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { rootRequest } from './common'; + +export const deleteRuntimeField = (dataView: string, fieldName: string) => { + const deleteRuntimeFieldPath = `/api/data_views/data_view/${dataView}/runtime_field/${fieldName}`; + + rootRequest({ + url: deleteRuntimeFieldPath, + method: 'DELETE', + failOnStatusCode: false, + }); +}; diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/timelines.ts b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/timelines.ts index 9b6a0c98db40..a4edcc54752d 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/timelines.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/api_calls/timelines.ts @@ -7,7 +7,7 @@ import type { TimelineResponse } from '@kbn/security-solution-plugin/common/api/timeline'; import type { CompleteTimeline } from '../../objects/timeline'; -import { rootRequest } from '../common'; +import { rootRequest } from './common'; export const createTimeline = (timeline: CompleteTimeline) => rootRequest({ @@ -56,11 +56,6 @@ export const createTimeline = (timeline: CompleteTimeline) => : {}), }, }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - 'elastic-api-version': '2023-10-31', - }, }); export const createTimelineTemplate = (timeline: CompleteTimeline) => @@ -106,14 +101,12 @@ export const createTimelineTemplate = (timeline: CompleteTimeline) => savedQueryId: null, }, }, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, }); export const loadPrepackagedTimelineTemplates = () => rootRequest({ method: 'POST', url: 'api/timeline/_prepackaged', - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, }); export const favoriteTimeline = ({ @@ -136,5 +129,4 @@ export const favoriteTimeline = ({ templateTimelineId: templateTimelineId || null, templateTimelineVersion: templateTimelineVersion || null, }, - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, }); diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/common.ts b/x-pack/test/security_solution_cypress/cypress/tasks/common.ts index a9b019fc1f6f..b7d0062cd5d0 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/common.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/common.ts @@ -5,13 +5,8 @@ * 2.0. */ -import { DATA_VIEW_PATH, INITIAL_REST_VERSION } from '@kbn/data-views-plugin/server/constants'; -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; import { KIBANA_LOADING_ICON } from '../screens/security_header'; import { EUI_BASIC_TABLE_LOADING } from '../screens/common/controls'; -import { deleteAllDocuments } from './api_calls/elasticsearch'; -import { DEFAULT_ALERTS_INDEX_PATTERN } from './api_calls/alerts'; -import { ELASTICSEARCH_PASSWORD, ELASTICSEARCH_USERNAME } from '../env_var_names_constants'; const primaryButton = 0; @@ -21,30 +16,6 @@ const primaryButton = 0; */ const dndSloppyClickDetectionThreshold = 5; -export const API_AUTH = Object.freeze({ - user: Cypress.env(ELASTICSEARCH_USERNAME), - pass: Cypress.env(ELASTICSEARCH_PASSWORD), -}); - -export const API_HEADERS = Object.freeze({ - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - [ELASTIC_HTTP_VERSION_HEADER]: [INITIAL_REST_VERSION], -}); - -export const rootRequest = ({ - headers: optionHeaders, - ...restOptions -}: Partial): Cypress.Chainable> => - cy.request({ - auth: API_AUTH, - headers: { - ...API_HEADERS, - ...(optionHeaders || {}), - }, - ...restOptions, - }); - /** Starts dragging the subject */ export const drag = (subject: JQuery) => { const subjectLocation = subject[0].getBoundingClientRect(); @@ -99,243 +70,6 @@ export const resetRulesTableState = () => { clearSessionStorage(); }; -export const deleteAlertsAndRules = () => { - cy.log('Delete all alerts and rules'); - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - - rootRequest({ - method: 'POST', - url: '/api/detection_engine/rules/_bulk_action', - body: { - query: '', - action: 'delete', - }, - failOnStatusCode: false, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - }, - timeout: 300000, - }); - - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'alert', - }, - }, - ], - }, - }, - }, - }); - - deleteAllDocuments(`.lists-*,.items-*,${DEFAULT_ALERTS_INDEX_PATTERN}`); -}; - -export const deleteExceptionLists = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'exception-list', - }, - }, - ], - }, - }, - }, - }); -}; - -export const deleteEndpointExceptionList = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'exception-list-agnostic', - }, - }, - ], - }, - }, - }, - }); -}; - -export const deleteTimelines = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'siem-ui-timeline', - }, - }, - ], - }, - }, - }, - }); -}; - -export const deleteAlertsIndex = () => { - rootRequest({ - method: 'POST', - url: '/api/index_management/indices/delete', - body: { indices: ['.internal.alerts-security.alerts-default-000001'] }, - failOnStatusCode: false, - }); -}; - -export const deleteAllCasesItems = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_alerting_cases_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - bool: { - should: [ - { - term: { - type: 'cases', - }, - }, - { - term: { - type: 'cases-configure', - }, - }, - { - term: { - type: 'cases-comments', - }, - }, - { - term: { - type: 'cases-user-action', - }, - }, - { - term: { - type: 'cases-connector-mappings', - }, - }, - ], - }, - }, - ], - }, - }, - }, - }); -}; - -export const deleteConnectors = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_alerting_cases_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'action', - }, - }, - ], - }, - }, - }, - }); -}; - -export const deletePrebuiltRulesAssets = () => { - const kibanaIndexUrl = `${Cypress.env('ELASTICSEARCH_URL')}/.kibana_\*`; - rootRequest({ - method: 'POST', - url: `${kibanaIndexUrl}/_delete_by_query?conflicts=proceed&refresh`, - body: { - query: { - bool: { - filter: [ - { - match: { - type: 'security-rule', - }, - }, - ], - }, - }, - }, - }); -}; - -export const postDataView = (indexPattern: string, name?: string, id?: string) => { - rootRequest({ - method: 'POST', - url: DATA_VIEW_PATH, - body: { - data_view: { - id: id || indexPattern, - name: name || indexPattern, - fieldAttrs: '{}', - title: indexPattern, - timeFieldName: '@timestamp', - }, - }, - headers: { - 'kbn-xsrf': 'cypress-creds', - 'x-elastic-internal-origin': 'security-solution', - }, - failOnStatusCode: false, - }); -}; - -export const deleteDataView = (dataViewId: string) => { - rootRequest({ - method: 'POST', - url: 'api/content_management/rpc/delete', - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, - body: { - contentTypeId: 'index-pattern', - id: dataViewId, - options: { force: true }, - version: 1, - }, - failOnStatusCode: false, - }); -}; - export const scrollToBottom = () => cy.scrollTo('bottom'); export const waitForWelcomePanelToBeLoaded = () => { diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/exceptions_table.ts b/x-pack/test/security_solution_cypress/cypress/tasks/exceptions_table.ts index c3af909131cd..710526bdff18 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/exceptions_table.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/exceptions_table.ts @@ -5,7 +5,12 @@ * 2.0. */ -import { INPUT_FILE, TOASTER, TOASTER_BODY } from '../screens/alerts_detection_rules'; +import { + INPUT_FILE, + TOASTER, + TOASTER_BODY, + TOASTER_CLOSE_ICON, +} from '../screens/alerts_detection_rules'; import { EXCEPTIONS_TABLE, EXCEPTIONS_TABLE_SEARCH, @@ -70,6 +75,12 @@ export const exportExceptionList = (listId: string) => { .click(); cy.get(EXCEPTIONS_TABLE_EXPORT_MODAL_BTN).first().click(); cy.get(EXCEPTIONS_TABLE_EXPIRED_EXCEPTION_ITEMS_MODAL_CONFIRM_BTN).first().click(); + cy.root().then(($page) => { + const element = $page.find(TOASTER_CLOSE_ICON); + if (element.length > 0) { + closeErrorToast(); + } + }); }; export const assertNumberLinkedRules = (listId: string, numberOfRulesAsString: string) => { diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts index 4bf71413f8a5..4df97fd86461 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/login.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/login.ts @@ -12,13 +12,13 @@ import { LoginState } from '@kbn/security-plugin/common/login_state'; import type { SecurityRoleName } from '@kbn/security-solution-plugin/common/test'; import { KNOWN_SERVERLESS_ROLE_DEFINITIONS } from '@kbn/security-solution-plugin/common/test'; import { LOGOUT_URL } from '../urls/navigation'; -import { API_HEADERS, rootRequest } from './common'; import { CLOUD_SERVERLESS, ELASTICSEARCH_PASSWORD, ELASTICSEARCH_USERNAME, IS_SERVERLESS, } from '../env_var_names_constants'; +import { API_HEADERS, rootRequest } from './api_calls/common'; /** * Credentials in the `kibana.dev.yml` config file will be used to authenticate diff --git a/x-pack/test/security_solution_cypress/cypress/tasks/sourcerer.ts b/x-pack/test/security_solution_cypress/cypress/tasks/sourcerer.ts index 39a6ed99b1b2..a534fb3e6d3d 100644 --- a/x-pack/test/security_solution_cypress/cypress/tasks/sourcerer.ts +++ b/x-pack/test/security_solution_cypress/cypress/tasks/sourcerer.ts @@ -9,7 +9,6 @@ import { DEFAULT_ALERTS_INDEX } from '@kbn/security-solution-plugin/common/const import { HOSTS_STAT, SOURCERER } from '../screens/sourcerer'; import { hostsUrl } from '../urls/navigation'; import { openTimelineUsingToggle } from './security_main'; -import { rootRequest } from './common'; import { visitWithTimeRange } from './navigation'; export const openSourcerer = (sourcererScope?: string) => { @@ -130,14 +129,3 @@ export const refreshUntilAlertsIndexExists = async () => { { interval: 500, timeout: 12000 } ); }; - -export const deleteRuntimeField = (dataView: string, fieldName: string) => { - const deleteRuntimeFieldPath = `/api/data_views/data_view/${dataView}/runtime_field/${fieldName}`; - - rootRequest({ - url: deleteRuntimeFieldPath, - method: 'DELETE', - headers: { 'kbn-xsrf': 'cypress-creds', 'x-elastic-internal-origin': 'security-solution' }, - failOnStatusCode: false, - }); -}; diff --git a/x-pack/test/security_solution_cypress/serverless_config.ts b/x-pack/test/security_solution_cypress/serverless_config.ts index f302617f0e74..d0ee1613f6e4 100644 --- a/x-pack/test/security_solution_cypress/serverless_config.ts +++ b/x-pack/test/security_solution_cypress/serverless_config.ts @@ -34,9 +34,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { { product_line: 'endpoint', product_tier: 'complete' }, { product_line: 'cloud', product_tier: 'complete' }, ])}`, - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'disableTimelineSaveTour', - ])}`, ], }, testRunner: SecuritySolutionConfigurableCypressTestRunner, diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts index 061e8936bf24..3c31e714ae10 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_permissions.ts @@ -17,7 +17,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const testSubjects = getService('testSubjects'); const endpointTestResources = getService('endpointTestResources'); - describe('Endpoint permissions:', function () { + // FLAKY: https://github.com/elastic/kibana/issues/171649 + // FLAKY: https://github.com/elastic/kibana/issues/171650 + describe.skip('Endpoint permissions:', function () { targetTags(this, ['@ess']); let indexedData: IndexedHostsAndAlertsResponse; diff --git a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts index b48c64b5e9dd..a2b1feaabd7c 100644 --- a/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts +++ b/x-pack/test/security_solution_endpoint/apps/integrations/policy_details.ts @@ -28,7 +28,9 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const endpointTestResources = getService('endpointTestResources'); const retry = getService('retry'); - describe('When on the Endpoint Policy Details Page', function () { + // FLAKY: https://github.com/elastic/kibana/issues/171653 + // FLAKY: https://github.com/elastic/kibana/issues/171654 + describe.skip('When on the Endpoint Policy Details Page', function () { targetTags(this, ['@ess', '@serverless']); let indexedData: IndexedHostsAndAlertsResponse; diff --git a/x-pack/test/security_solution_endpoint/config.base.ts b/x-pack/test/security_solution_endpoint/config.base.ts index d75458a4c581..e3be9a2a6934 100644 --- a/x-pack/test/security_solution_endpoint/config.base.ts +++ b/x-pack/test/security_solution_endpoint/config.base.ts @@ -90,10 +90,6 @@ export const generateConfig = async ({ `--xpack.fleet.packages.0.version=latest`, // this will be removed in 8.7 when the file upload feature is released `--xpack.fleet.enableExperimental.0=diagnosticFileUploadEnabled`, - // disable a tour that prevents tests from passing - `--xpack.securitySolution.enableExperimental=${JSON.stringify([ - 'disableTimelineSaveTour', - ])}`, ...kbnServerArgs, ], }, diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts index f904539dae23..8d297f82befe 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_response_actions/execute.ts @@ -16,7 +16,9 @@ export default function ({ getService }: FtrProviderContext) { const supertestWithoutAuth = getService('supertestWithoutAuth'); const endpointTestResources = getService('endpointTestResources'); - describe('Endpoint `execute` response action', function () { + // FLAKY: https://github.com/elastic/kibana/issues/171667 + // FLAKY: https://github.com/elastic/kibana/issues/171666 + describe.skip('Endpoint `execute` response action', function () { targetTags(this, ['@ess', '@serverless']); let indexedData: IndexedHostsAndAlertsResponse; diff --git a/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts b/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts index 105620f90d6b..2d54d3ba0a52 100644 --- a/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts +++ b/x-pack/test/upgrade/apps/dashboard/dashboard_smoke_tests.ts @@ -14,6 +14,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const log = getService('log'); const renderable = getService('renderable'); const dashboardExpect = getService('dashboardExpect'); + const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'header', 'home', 'dashboard', 'timePicker']); const browser = getService('browser'); @@ -40,8 +41,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); dashboardTests.forEach(({ name, numPanels }) => { it('should launch sample ' + name + ' data set dashboard', async () => { + await kibanaServer.uiSettings.update({ + 'timepicker:timeDefaults': `{ "from": "now-5y", "to": "now"}`, + }); await PageObjects.home.launchSampleDashboard(name); - await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await PageObjects.header.waitUntilLoadingHasFinished(); await renderable.waitForRender(); const panelCount = await PageObjects.dashboard.getPanelCount(); @@ -49,9 +52,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); it('should render visualizations', async () => { + await kibanaServer.uiSettings.update({ + 'timepicker:timeDefaults': `{ "from": "now-5y", "to": "now"}`, + }); await PageObjects.home.launchSampleDashboard('flights'); await PageObjects.header.waitUntilLoadingHasFinished(); - await PageObjects.timePicker.setCommonlyUsedTime('Last_1 year'); await renderable.waitForRender(); log.debug('Checking saved searches rendered'); await dashboardExpect.savedSearchRowCount(49); diff --git a/x-pack/test_serverless/api_integration/services/saml_tools.ts b/x-pack/test_serverless/api_integration/services/saml_tools.ts index 4756109fc667..bd5cd03a7edb 100644 --- a/x-pack/test_serverless/api_integration/services/saml_tools.ts +++ b/x-pack/test_serverless/api_integration/services/saml_tools.ts @@ -6,33 +6,35 @@ */ import expect from '@kbn/expect'; -// eslint-disable-next-line @kbn/imports/no_boundary_crossing -import { getSAMLResponse } from '@kbn/security-api-integration-helpers/saml/saml_tools'; -import { kbnTestConfig } from '@kbn/test'; - import { parse as parseCookie } from 'tough-cookie'; +import Url from 'url'; +import { createSAMLResponse } from '@kbn/mock-idp-plugin/common'; import { FtrProviderContext } from '../ftr_provider_context'; export function SamlToolsProvider({ getService }: FtrProviderContext) { const supertestWithoutAuth = getService('supertestWithoutAuth'); - const randomness = getService('randomness'); const svlCommonApi = getService('svlCommonApi'); - - function createSAMLResponse(options = {}) { - return getSAMLResponse({ - destination: `http://localhost:${kbnTestConfig.getPort()}/api/security/saml/callback`, - sessionIndex: String(randomness.naturalNumber()), - ...options, - }); - } + const config = getService('config'); return { async login(username: string) { + const kibanaUrl = Url.format({ + protocol: config.get('servers.kibana.protocol'), + hostname: config.get('servers.kibana.hostname'), + port: config.get('servers.kibana.port'), + pathname: '/api/security/saml/callback', + }); const samlAuthenticationResponse = await supertestWithoutAuth .post('/api/security/saml/callback') .set(svlCommonApi.getCommonRequestHeader()) - .send({ SAMLResponse: await createSAMLResponse({ username }) }); + .send({ + SAMLResponse: await createSAMLResponse({ + username, + roles: [], + kibanaUrl, + }), + }); expect(samlAuthenticationResponse.status).to.equal(302); expect(samlAuthenticationResponse.header.location).to.equal('/'); const sessionCookie = parseCookie(samlAuthenticationResponse.header['set-cookie'][0])!; diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index.ts index 7dff563bf43b..e06aaf9225cf 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/index.ts @@ -14,5 +14,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./index_templates')); loadTestFile(require.resolve('./indices')); loadTestFile(require.resolve('./create_enrich_policies')); + loadTestFile(require.resolve('./mappings')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts index 9c4fd7b19633..70de83c949cf 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts @@ -5,10 +5,9 @@ * 2.0. */ -import expect from 'expect'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -const API_BASE_PATH = '/api/index_management'; const INTERNAL_API_BASE_PATH = '/internal/index_management'; const expectedKeys = ['aliases', 'hidden', 'isFrozen', 'primary', 'replica', 'name'].sort(); @@ -16,22 +15,27 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const es = getService('es'); const log = getService('log'); + const indexManagementService = getService('indexManagement'); describe('Indices', function () { - const indexName = `index-${Math.random()}`; + let indexName: string; + let reload: typeof indexManagementService['indices']['api']['reload']; + let list: typeof indexManagementService['indices']['api']['list']; + let deleteIndex: typeof indexManagementService['indices']['api']['deleteIndex']; + let createIndex: typeof indexManagementService['indices']['helpers']['createIndex']; + let deleteAllIndices: typeof indexManagementService['indices']['helpers']['deleteAllIndices']; + let catIndex: typeof indexManagementService['indices']['helpers']['catIndex']; before(async () => { - // Create a new index to test against - const indexExists = await es.indices.exists({ index: indexName }); - - // Index should not exist, but in the case that it already does, we bypass the create request - if (indexExists) { - return; - } - + ({ + indices: { + api: { reload, list, deleteIndex }, + helpers: { createIndex, deleteAllIndices, catIndex }, + }, + } = indexManagementService); log.debug(`Creating index: '${indexName}'`); try { - await es.indices.create({ index: indexName }); + indexName = await createIndex(); } catch (err) { log.debug('[Setup error] Error creating index'); throw err; @@ -41,28 +45,27 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { // Cleanup index created for testing purposes try { - await es.indices.delete({ - index: indexName, - }); + await deleteAllIndices(); } catch (err) { log.debug('[Cleanup error] Error deleting index'); throw err; } }); - describe('get all', () => { - it('should list indices with the expected parameters', async () => { - const { body: indices } = await supertest - .get(`${API_BASE_PATH}/indices`) - .set('kbn-xsrf', 'xxx') - .set('x-elastic-internal-origin', 'xxx') - .expect(200); + describe('list', () => { + it('should list all the indices with the expected properties', async function () { + // Create an index that we can assert against + await createIndex('test_index'); - const indexFound = indices.find((index: { name: string }) => index.name === indexName); + // Verify indices request + const { body: indices } = await list().set('x-elastic-internal-origin', 'xxx').expect(200); - expect(indexFound).toBeTruthy(); + // Find the "test_index" created to verify expected keys + const indexCreated = indices.find((index: { name: string }) => index.name === 'test_index'); - expect(Object.keys(indexFound).sort()).toEqual(expectedKeys); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + + expect(sortedReceivedKeys).to.eql(expectedKeys); }); }); @@ -74,9 +77,9 @@ export default function ({ getService }: FtrProviderContext) { .set('x-elastic-internal-origin', 'xxx') .expect(200); - expect(index).toBeTruthy(); + expect(index).to.be.ok(); - expect(Object.keys(index).sort()).toEqual(expectedKeys); + expect(Object.keys(index).sort()).to.eql(expectedKeys); }); it('throws 404 for a non-existent index', async () => { @@ -118,9 +121,9 @@ export default function ({ getService }: FtrProviderContext) { .set('x-elastic-internal-origin', 'xxx') .expect(200); - expect(index).toBeTruthy(); + expect(index).to.be.ok(); - expect(Object.keys(index).sort()).toEqual(expectedKeys); + expect(Object.keys(index).sort()).to.eql(expectedKeys); }); it('fails to re-create the same index', async () => { @@ -134,5 +137,47 @@ export default function ({ getService }: FtrProviderContext) { .expect(400); }); }); + + describe('reload', function () { + it('should list all the indices with the expected properties', async function () { + // create an index to assert against, otherwise the test is flaky + await createIndex('reload-test-index'); + const { body } = await reload().set('x-elastic-internal-origin', 'xxx').expect(200); + + const indexCreated = body.find( + (index: { name: string }) => index.name === 'reload-test-index' + ); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + expect(sortedReceivedKeys).to.eql(expectedKeys); + expect(body.length > 1).to.be(true); // to contrast it with the next test + }); + + it('should allow reloading only certain indices', async () => { + const index = await createIndex(); + const { body } = await reload([index]).set('x-elastic-internal-origin', 'xxx'); + + expect(body.length === 1).to.be(true); + expect(body[0].name).to.be(index); + }); + }); + + describe('delete indices', () => { + it('should delete an index', async () => { + const index = await createIndex(); + + const { body: indices1 } = await catIndex(undefined, 'i'); + expect(indices1.map((indexItem) => indexItem.i)).to.contain(index); + + await deleteIndex(index).set('x-elastic-internal-origin', 'xxx').expect(200); + + const { body: indices2 } = await catIndex(undefined, 'i'); + expect(indices2.map((indexItem) => indexItem.i)).not.to.contain(index); + }); + + it('should require index or indices to be provided', async () => { + const { body } = await deleteIndex().set('x-elastic-internal-origin', 'xxx').expect(400); + expect(body.message).to.contain('expected value of type [string]'); + }); + }); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/mappings.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/mappings.ts new file mode 100644 index 000000000000..eb28c77fc440 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/mappings.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getService }: FtrProviderContext) { + const log = getService('log'); + const indexManagementService = getService('indexManagement'); + + describe('mappings', () => { + let indexName: string; + let getMapping: typeof indexManagementService['mappings']['api']['getMapping']; + let createIndex: typeof indexManagementService['indices']['helpers']['createIndex']; + let deleteAllIndices: typeof indexManagementService['indices']['helpers']['deleteAllIndices']; + + const mappings = { + properties: { + total: { type: 'long' }, + tag: { type: 'keyword' }, + createdAt: { type: 'date' }, + }, + }; + + before(async () => { + ({ + indices: { + helpers: { createIndex, deleteAllIndices }, + }, + mappings: { + api: { getMapping }, + }, + } = indexManagementService); + + log.debug('Creating index'); + try { + indexName = await createIndex(undefined, mappings); + } catch (err) { + log.debug('[Setup error] Error creating index'); + throw err; + } + }); + + after(async () => { + try { + await deleteAllIndices(); + } catch (err) { + log.debug('[Cleanup error] Error deleting index'); + throw err; + } + }); + + it('should get the index mappings', async () => { + const { body } = await getMapping(indexName).expect(200); + + expect(body.mappings).to.eql(mappings); + }); + }); +} diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts index 2b7fc3653c3b..055f6c1a17a5 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_fired.ts @@ -6,7 +6,6 @@ */ import { cleanup, generate } from '@kbn/infra-forge'; -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -89,7 +88,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.5], timeSize: 5, @@ -184,7 +182,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [0.5], timeSize: 5, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts index 4f1e9a4ab080..098f4659fdd2 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/avg_pct_no_data.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -75,7 +74,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.5], timeSize: 5, @@ -170,7 +168,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [0.5], timeSize: 5, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts index 47ed54412296..0c3f43b29fdd 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/custom_eq_avg_bytes_fired.ts @@ -12,7 +12,6 @@ */ import { cleanup, generate } from '@kbn/infra-forge'; -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -91,7 +90,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.9], timeSize: 1, @@ -188,7 +186,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [0.9], timeSize: 1, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts index 0f47627be5e2..01f04b12f0c5 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/documents_count_fired.ts @@ -6,7 +6,6 @@ */ import { cleanup, generate } from '@kbn/infra-forge'; -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { Aggregators, Comparator, @@ -85,7 +84,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT, threshold: [2], timeSize: 1, @@ -178,7 +176,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>', threshold: [2], timeSize: 1, diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts index 78daabb1eb13..0f7b7a019cc8 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/custom_threshold_rule/group_by_fired.ts @@ -11,7 +11,6 @@ * 2.0. */ -import { CUSTOM_AGGREGATOR } from '@kbn/observability-plugin/common/custom_threshold_rule/constants'; import { kbnTestConfig } from '@kbn/test'; import moment from 'moment'; import { cleanup, generate } from '@kbn/infra-forge'; @@ -95,7 +94,6 @@ export default function ({ getService }: FtrProviderContext) { params: { criteria: [ { - aggType: CUSTOM_AGGREGATOR, comparator: Comparator.GT_OR_EQ, threshold: [0.2], timeSize: 1, @@ -205,7 +203,6 @@ export default function ({ getService }: FtrProviderContext) { .eql({ criteria: [ { - aggType: 'custom', comparator: '>=', threshold: [0.2], timeSize: 1, @@ -235,8 +232,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.custom_threshold'); expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql( - // Added the S to protocol.getUrlParts as not returning the correct value. - `${protocol}s://${hostname}:${port}/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)` + `${protocol}://${hostname}:${port}/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)` ); expect(resp.hits.hits[0]._source?.reason).eql( `Average system.cpu.total.norm.pct is 80%, above the threshold of 20%. (duration: 1 min, data view: ${DATE_VIEW}, group: host-0)` diff --git a/x-pack/test_serverless/functional/test_suites/common/platform_security/index.ts b/x-pack/test_serverless/functional/test_suites/common/platform_security/index.ts index bbcd138e2016..bbb66a984186 100644 --- a/x-pack/test_serverless/functional/test_suites/common/platform_security/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/platform_security/index.ts @@ -11,5 +11,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('Serverless Common UI - Platform Security', function () { loadTestFile(require.resolve('./api_keys')); loadTestFile(require.resolve('./navigation/avatar_menu')); + loadTestFile(require.resolve('./user_profiles/user_profiles')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts b/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts new file mode 100644 index 000000000000..57ef995a4f7a --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/common/platform_security/user_profiles/user_profiles.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ getPageObjects }: FtrProviderContext) { + const pageObjects = getPageObjects(['svlCommonPage', 'common', 'userProfiles']); + + describe('User Profile Page', async () => { + before(async () => { + await pageObjects.svlCommonPage.login(); + }); + + describe('Theme', async () => { + it('should change theme based on the User Profile Theme control', async () => { + await pageObjects.common.navigateToApp('security_account'); + + const themeKeyPadMenu = await pageObjects.userProfiles.getThemeKeypadMenu(); + expect(themeKeyPadMenu).not.to.be(null); + + await pageObjects.userProfiles.changeUserProfileTheme('Dark'); + const darkModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(darkModeTag).to.be('v8dark'); + + await pageObjects.userProfiles.changeUserProfileTheme('Light'); + const lightModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(lightModeTag).to.be('v8light'); + + await pageObjects.userProfiles.changeUserProfileTheme('Space default'); + const spaceDefaultModeTag = await pageObjects.userProfiles.getThemeTag(); + expect(spaceDefaultModeTag).to.be('v8light'); + }); + }); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/security/ml/data_frame_analytics_jobs_list.ts b/x-pack/test_serverless/functional/test_suites/security/ml/data_frame_analytics_jobs_list.ts index f0dbed0ca9a7..3a4153b264cc 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ml/data_frame_analytics_jobs_list.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ml/data_frame_analytics_jobs_list.ts @@ -20,7 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await PageObjects.svlCommonPage.login(); await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ihp_outlier'); - await ml.testResources.createIndexPatternIfNeeded('ft_ihp_outlier', '@timestamp'); + await ml.testResources.createDataViewIfNeeded('ft_ihp_outlier', '@timestamp'); await ml.api.createDataFrameAnalyticsJob( ml.commonConfig.getDFAIhpOutlierDetectionJobConfig(dfaJobId) diff --git a/x-pack/test_serverless/shared/config.base.ts b/x-pack/test_serverless/shared/config.base.ts index ec11099f946c..6dee26203b53 100644 --- a/x-pack/test_serverless/shared/config.base.ts +++ b/x-pack/test_serverless/shared/config.base.ts @@ -16,15 +16,16 @@ import { kibanaTestSuperuserServerless, getDockerFileMountPath, } from '@kbn/test'; -import { CA_CERT_PATH, KBN_CERT_PATH, KBN_KEY_PATH, kibanaDevServiceAccount } from '@kbn/dev-utils'; +import { CA_CERT_PATH, kibanaDevServiceAccount } from '@kbn/dev-utils'; import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; +import { MOCK_IDP_REALM_NAME } from '@kbn/mock-idp-plugin/common'; import { services } from './services'; export default async () => { const servers = { kibana: { ...kbnTestConfig.getUrlParts(kibanaTestSuperuserServerless), - protocol: 'https', + protocol: process.env.TEST_CLOUD ? 'https' : 'http', certificateAuthorities: process.env.TEST_CLOUD ? undefined : [Fs.readFileSync(CA_CERT_PATH)], }, elasticsearch: { @@ -68,16 +69,6 @@ export default async () => { 'xpack.security.authc.realms.jwt.jwt1.order=-98', `xpack.security.authc.realms.jwt.jwt1.pkc_jwkset_path=${getDockerFileMountPath(jwksPath)}`, `xpack.security.authc.realms.jwt.jwt1.token_type=access_token`, - - 'xpack.security.authc.realms.saml.cloud-saml-kibana.attributes.principal=urn:oid:0.0.7', - 'xpack.security.authc.realms.saml.cloud-saml-kibana.idp.entity_id=http://www.elastic.co/saml1', - 'xpack.security.authc.realms.saml.cloud-saml-kibana.order=101', - `xpack.security.authc.realms.saml.cloud-saml-kibana.idp.metadata.path=${getDockerFileMountPath( - idpPath - )}`, - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.acs=http://localhost:${servers.kibana.port}/api/security/saml/callback`, - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.entity_id=http://localhost:${servers.kibana.port}`, - `xpack.security.authc.realms.saml.cloud-saml-kibana.sp.logout=http://localhost:${servers.kibana.port}/logout`, ], ssl: true, // SSL is required for SAML realm }, @@ -89,10 +80,6 @@ export default async () => { }, sourceArgs: ['--no-base-path', '--env.name=development'], serverArgs: [ - '--server.ssl.enabled=true', - `--server.ssl.key=${KBN_KEY_PATH}`, - `--server.ssl.certificate=${KBN_CERT_PATH}`, - `--server.ssl.certificateAuthorities=${CA_CERT_PATH}`, `--server.restrictInternalApis=true`, `--server.port=${servers.kibana.port}`, '--status.allowAnonymous=true', @@ -147,7 +134,7 @@ export default async () => { // user navigates to `/login` page directly and enters username and password in the login form. '--xpack.security.authc.selector.enabled=false', `--xpack.security.authc.providers=${JSON.stringify({ - saml: { 'cloud-saml-kibana': { order: 0, realm: 'cloud-saml-kibana' } }, + saml: { 'cloud-saml-kibana': { order: 0, realm: MOCK_IDP_REALM_NAME } }, basic: { 'cloud-basic': { order: 1 } }, })}`, '--xpack.encryptedSavedObjects.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"', diff --git a/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml b/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml index a8f7adfc8577..8b0627d960a4 100644 --- a/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml +++ b/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml @@ -240,6 +240,7 @@ t3_analyst: privileges: - read - write + - maintenance - names: - .lists* - .items* @@ -293,12 +294,16 @@ threat_intelligence_analyst: - endgame-* - filebeat-* - logs-* - - .lists* - - .items* - packetbeat-* - winlogbeat-* privileges: - read + - names: + - .lists* + - .items* + privileges: + - read + - write - names: - .alerts-security* - .siem-signals-* @@ -317,8 +322,7 @@ threat_intelligence_analyst: - application: "kibana-.kibana" privileges: - feature_ml.read - - feature_siem.read - - feature_siem.read_alerts + - feature_siem.all - feature_siem.endpoint_list_read - feature_siem.blocklist_all - feature_securitySolutionCases.all @@ -603,6 +607,7 @@ endpoint_operations_analyst: privileges: - read - write + - maintenance applications: - application: "kibana-.kibana" privileges: @@ -653,11 +658,15 @@ endpoint_policy_manager: - logs-* - packetbeat-* - winlogbeat-* + - risk-score.risk-score-* + privileges: + - read + - names: - .lists* - .items* - - risk-score.risk-score-* privileges: - read + - write - names: - .alerts-security* - .siem-signals-* diff --git a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts index 4721a6f71d10..ce922732796f 100644 --- a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts +++ b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts @@ -21,6 +21,7 @@ const deploymentAgnosticApiIntegrationServices = _.pick(apiIntegrationServices, 'esSupertest', 'indexPatterns', 'ingestPipelines', + 'indexManagement', 'kibanaServer', 'ml', 'randomness', diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index e825bff536d8..6f843b935d63 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -48,7 +48,6 @@ "@kbn/rison", "@kbn/discover-plugin", "@kbn/data-plugin", - "@kbn/security-api-integration-helpers", "@kbn/std", "@kbn/data-view-field-editor-plugin", "@kbn/data-plugin", @@ -68,5 +67,6 @@ "@kbn/apm-synthtrace", "@kbn/apm-synthtrace-client", "@kbn/reporting-export-types-csv-common", + "@kbn/mock-idp-plugin", ] } diff --git a/yarn.lock b/yarn.lock index f9b51eea5202..6eba5c6fe3da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5069,10 +5069,18 @@ version "0.0.0" uid "" +"@kbn/ml-ui-actions@link:x-pack/packages/ml/ui_actions": + version "0.0.0" + uid "" + "@kbn/ml-url-state@link:x-pack/packages/ml/url_state": version "0.0.0" uid "" +"@kbn/mock-idp-plugin@link:packages/kbn-mock-idp-plugin": + version "0.0.0" + uid "" + "@kbn/monaco@link:packages/kbn-monaco": version "0.0.0" uid "" @@ -5929,10 +5937,6 @@ version "0.0.0" uid "" -"@kbn/subscription-tracking@link:packages/kbn-subscription-tracking": - version "0.0.0" - uid "" - "@kbn/synthetics-plugin@link:x-pack/plugins/synthetics": version "0.0.0" uid ""